我有一个脚本,它设置一组用户名,然后为每个用户名运行一个读取请求,以抽动APIendpoint来获取每个用户的Json信息。然后我想把这些信息放在一个数组中供以后使用,发现我必须使用promise,这是我以前从未使用过的。我读了这个:https://developers.google.com/web/fundamentals/primers/promises和这个:https://github.com/domenic/promises-unwrapping/blob/master/docs/states-and-fates.md,我在这里读到费利克斯·克林的响应:我如何从异步调用返回响应?我仍然无法准确理解什么去了哪里,什么做了什么。这是我到目前为止所拥有的:
var users = ["ESL_SC2", "OgamingSC2", "cretetion", "freecodecamp", "storbeck", "habathcx", "RobotCaleb", "noobs2ninjas"]
var arr = [];
var headers = {
'Client-Id': 'xxxxxxxxxxx'
}
var promise = new Promise(function usersJson(callback) {
for (i = 0; i < users.length; i++) {
var url = "https://api.twitch.tv/helix/users?login=" + users[i];
fetch(url, {headers})
.then(function(response) {
return response.json();
})
.then(function(myJson) {
arr.push(myJson);
})
callback(arr);
};
})
promise.then(function(result) {
console.log(result);
})
据我所知,这应该贯穿每个endpoint,将数据推送到我的数组变量,然后一旦整个事情“实现”,它应该调用带有我的promise变量的“然后”来console.log我的数组。我得到的只是一个空白数组,我真的不确定我做错了什么。如果我把console.log(arr)在arr.push(json)之后,我得到8个数组返回,每个数组都有下一个响应体,所以我知道调用是工作的,我只是不能让它坚持我的阵列。
做这样的事情代替:
const runTheTrap = async function(users){
const ret = [];
for (i = 0; i < users.length; i++) {
var url = "https://api.twitch.tv/helix/users?login=" + users[i];
await fetch(url, {headers})
.then(function(r) {
return r.json().then(v => ret.push(v));
});
};
return ret;
}
runTheTrap(users).then(function(result) {
console.log(result);
});
但坦率地说,异步/等待有点拖沓,我更喜欢这种方法:
const runTheTrap = function(users){
return users.map(function(u){
var url = "https://api.twitch.tv/helix/users?login=" + u;
return fetch(url, {headers}).then(r => {
return r.json();
});
}
Promise.all(runTheTrap(users)).then(function(vals){
// you have your vals
});
为了得到您想要的结果,您的代码可以重写为
const users = ["ESL_SC2", "OgamingSC2", "cretetion", "freecodecamp", "storbeck", "habathcx", "RobotCaleb", "noobs2ninjas"]
const headers = {
'Client-Id': 'xxxxxxxxxxx'
}
Promise.all(users.map(user => fetch(`https://api.twitch.tv/helix/users?login=${user}`, {headers}).then(response => response.json())))
.then(result => console.log(result));
更具可读性
const users = ["ESL_SC2", "OgamingSC2", "cretetion", "freecodecamp", "storbeck", "habathcx", "RobotCaleb", "noobs2ninjas"]
const headers = {
'Client-Id': 'xxxxxxxxxxx'
}
const mapper = user =>
fetch(`https://api.twitch.tv/helix/users?login=${user}`, {headers})
.then(response => response.json());
const promises = users.map(mapper);
Promise.all(promises)
.then(result => console.log(result));
最后,由于您的原始代码显示不了解ES2015
var users = ["ESL_SC2", "OgamingSC2", "cretetion", "freecodecamp", "storbeck", "habathcx", "RobotCaleb", "noobs2ninjas"];
var headers = {
'Client-Id': 'xxxxxxxxxxx'
};
var mapper = function mapper(user) {
return fetch("https://api.twitch.tv/helix/users?login=" + user, { headers: headers }).then(function (response) {
return response.json();
});
};
var promises = users.map(mapper);
Promise.all(promises).then(function (result) {
return console.log(result);
});
一种可能帮助你在promise中思考更多的方法是,一旦你在promise之地,你只能在你还在promise之地的时候获得数据。在您的示例中,您从fetch
promise获取数据。这意味着您只能从fetch
promise内部使用该数据。请注意:
.then(function(myJson) {
arr.push(myJson);
})
callback(arr);
构建阵列的arr.push
在promise内部,而callback(arr)
在promise外部。因为你已经不在promise范围之内了,所以你无法获得数据。
在您的情况下,您还希望同时等待多个promise,因为您同时从多个源获取数据。最好的方法是使用Promise.all和一组promise:
const promise = Promise.all(users.map(user => {
const url = `https://api.twitch.tv/helix/users?login=${user}`;
return fetch(url, { headers })
.then(function(response) {
return response.json();
});
}));
现在,promise。然后,
将允许您在解决所有promise后访问一组数据。您不需要推送到另一个数组,。map
将为您创建一系列promise。
您还可以使用async
/await
语法编写此代码,该语法更易于推理,而且可能更简洁。
const promise = Promise.all(users.map(async user => {
const url = `https://api.twitch.tv/helix/users?login=${user}`;
const response = await fetch(url, { headers });
return response.json();
}));
顺便说一句,当使用本身不实现promise的库时,您应该只需要使用newpromise
fetch
已经返回了一个promise,所以当你调用它时,你已经得到了一个promise,所以没有必要用new Promise
来包装它。
是否有可能在函数的上下文中解析(实现)一个promise对象?是否有其他方法处理这个问题? UPD:这个代码对我有效。谢了!
新手,大佬轻点喷,vue2项目,搜索框用的原生,请求数据用的axios 我在项目中写了一个搜索框,目前数据的静态的,我想动态获取数据,但数据是异步请求获取的,如果我像下面直接这样赋值会获取不到值,我想使用promise改写,请问以下应当如何改写 代码:
问题内容: 我正在写一个如下的shell脚本: 现在,我想要实现的是列出$ ACTIONS_DIR中的每个文件以执行该文件。$ ACTIONS_DIR下的每个文件都是另一个Shell脚本。 现在,这里的问题在于,使用exec之后,脚本将停止并且不会转到下一个文件。任何想法为什么会这样? 问题答案: 替换shell进程。如果只想将该命令作为子进程调用,则将其删除。
问题内容: 我希望服务器每分钟执行一次节点脚本。如果我手动执行文件(),该程序将完美执行,因此,我很确定这不是问题。但是,当我将其交给cron执行时,什么也没发生。 这是cron文件中的行。 这是一个示例日志: 可执行文件: 知道我为什么要广播静音吗?我应该在其他地方调试? 更新: 我相信问题与我的相对文件路径有关,并且main.js从其自己的目录外部执行。 所以现在,我已经放置在目录中。看起来像
它涵盖了哪些用例?何时应该使用而不是常规的? 这个问题与硒有关,但与语言无关。
问题内容: 如何在Linux中从C执行Shell脚本? 问题答案: 这取决于您要对脚本(或要运行的任何其他程序)执行的操作。 如果只想运行脚本,这是最容易的事情,但是它也做其他一些事情,包括运行shell并让其运行命令(在大多数* nix下是/ bin / sh)。 如果您要通过标准输入来输入shell脚本或使用其标准输出,则可以使用(和)设置管道。这也使用外壳程序(大多数* nix下是/ bin