您好我是NodeJs的新手,我正在努力找到让这一系列事件发挥作用的最佳方法。我必须做两个API调用才能获得我需要的所有信息。第一个API调用只是一个ID列表,然后第二个API调用我传递ID以获取每个对象的其余信息。
然而,使用下面的方法,我不知道什么时候完成。请有人帮助我。
#lib/MyApp/guardian_serializer.ex
defmodule MyApp.GuardianSerializer do
@behaviour Guardian.Serializer
alias MyApp.Repo
alias MyApp.User
def for_token(user = %User{}), do: {:ok, "User:#{user.id}"}
def for_token(_), do: {:error, "Unknown resource type"}
def from_token("User:" <> id), do: {:ok, Repo.get(User, id)}
def from_token(_), do: {:error, "Unknown resource type"}
end
答案 0 :(得分:2)
你可以让你的findMore方法返回一个promise,这样你就可以将一个数组传递给Promise.all并在所有promises完成后处理.then。
function getData() {
var options = {
method: 'GET',
uri: 'https://api.call1.com',
qs: {
access_token: _accessToken,
}
};
request(options).then(function(apires){
console.log("complete 1");
var obj = JSON.parse(apires);
var promises = [];
obj.data.forEach(function(entry) {
promises.push(findMore(entry.id));
});
return Promise.all(promises);
})
.then(function (response) {
// Here response is an array with all the responses
// from your calls to findMore
})
}
function findMore(id) {
var options = {
method: 'GET',
uri: 'https://api.call2.com',
qs: {
access_token: _accessToken,
}
};
return request(options);
}
答案 1 :(得分:1)
要考虑的几件事情:
如果您关心承诺的命运,请务必将其归还。
在您的情况下,findMore
不会从request
返回承诺,因此getData
无法跟踪该承诺的解决(或拒绝)。
您可以使用Promise.all跟踪多个承诺的分辨率。
Promise.all()方法返回一个Promise,它在iterable参数中的所有promise都已解析或者iterable参数不包含promise时解析。它拒绝承认拒绝的第一个承诺。
让我们在你的例子中使用这些:
function getData() {
var options = {
method: 'GET',
uri: 'https://api.call1.com',
qs: {
access_token: _accessToken,
}
};
return request(options)
.then(function(apires){
var obj = JSON.parse(apires);
var findMorePromises = obj.data.map(function(entry) {
return findMore(entry.id)
});
return Promise.all(findMorePromises);
})
}
function findMore(id) {
var options = {
method: 'GET',
uri: 'https://api.call2.com',
qs: {
access_token: _accessToken,
}
};
return request(options)
.then(function(apires){
return JSON.parse(apires);
})
}
我已经使用map构建了promises数组,但您也可以使用foreach
并推入类似于您的示例代码的数组。< / p>
确保你处理任何承诺的拒绝(通过catch
)也是一种很好的做法,但我认为这不属于这个问题的范围。
答案 2 :(得分:0)
您想使用Promise.all。
首先,首先需要一系列承诺。在每个循环中,将findMore设置为变量,并使其返回promise。然后有一行你在哪里做Promise.all(promiseArr).then(function(){console.log(“done)})
您的代码看起来像这样
print '@totalCount'
print '------------'
print @totalCount
Promise.all的基本思想是,只有在数组中的所有承诺都已解决或任何承诺失败时才会执行。您可以阅读更多相关信息here
答案 3 :(得分:0)
您需要使用Promise.all
并行运行所有异步请求。此外,您必须返回findMore
和getData
的结果(它们是承诺)。
function getData() {
var options = {...};
return request(options)
.then(function(apires) {
console.log("complete 1");
var obj = JSON.parse(apires);
var ops = obj.data.map(function(entry) {
return findMore(entry.id);
});
return Promise.all(ops);
}
function findMore(id) {
var options = {...};
return request(options)
.then(function(apires) {
console.log("complete 2");
return JSON.parse(apires);
});
}
getData()
.then(data => console.log(data))
.catch(err => console.log(err));
如果您可以使用ES7,可以使用async / await编写:
let getData = async () => {
let options = {...};
let res = awit request(options);
let ops = res.data.map(entry => findMore(entry.id));
let data = await Promise.all(ops);
return data;
};
let findMore = async (id) => {
let options = {...};
let apires = awit request(options);
return JSON.parse(apires);
};
答案 4 :(得分:0)
如果您愿意使用jQuery(JavaScript库),那么您可以使用.ajaxStop()事件处理程序并指定您自己的函数。示例代码:
$(document).ajaxStop(function(){
alert("All AJAX requests are completed.");
});
您需要包含jQuery模块。 Node.js的说明是:
通过npm安装模块:
npm install jquery
然后使用“require”在JavaScript代码中使用jQuery(需要一个包含文档的窗口,但Node中没有这样的“窗口”,因此您可以使用jsdom模拟一个),请参阅{{3有关详细信息:
require("jsdom").env("", function(err, window) {
if (err) {
console.error(err);
return;
}
var $ = require("jquery")(window);
});
如果您想坚持使用纯JavaScript方法,则需要创建自己的“模块”来跟踪AJAX请求。在此模块中,您可以跟踪有多少待处理请求,并在终止后删除它们。有关详细信息,请参阅:npm - jQuery。