【发布时间】:2017-06-21 05:09:40
【问题描述】:
这里是 Node.js 的新手。我正在寻找从另一个函数中进行 N 个异步 API 调用的正确方法,并将它们的结果结合起来以进一步使用下游。在我的情况下,N 会相当小,并且阻塞它们的执行也不会太糟糕。
在同步执行中,下面的 combine() 实现应该可以工作。
如果我只需要一个 API 调用的结果,那么在提供给 callAPI() 的回调函数中实现以下逻辑将很简单。我绊倒的地方是我需要在执行 foo(total, [...args]) 之前合并所有结果。
我查看了async.whilst,但无法让它发挥作用。我怀疑这是否真的适合我的需求。我还研究了Promises,这似乎是正确的线索,但在爬进那个海绵状的兔子洞之前得到保证会很好。不管Promises是正确的方式,哪个模块是Node.js项目中使用的标准?
var http = require('http');
function callAPI(id) {
var options = {
host: 'example.com',
path: '/q/result/'.concat(id)
}
var req = http.get(options, (res) => {
var body = [];
res.on('data', (chunk) => {
body.push(chunk);
}).on('end', () => {
body = Buffer.concat(body).toString();
return body;
}).on('error', (err) => {
console.error(err);
});
});
}
function combine(inputs) {
var total = 0;
for (i=0; i < inputs.length; i++) {
total += callAPI(inputs[i]['id']);
};
console.log(total);
// call some function, foo(total, [...args])
}
编辑 1:
我尝试按照下面 samanime 的回答修改 API 调用以返回 Promise。见:
function callAPI(id) {
return Promise((resolve, reject) => {
var options = {
host: 'example.com',
path: '/q/result/'.concat(id)
}
var req = http.get(options, (res) => {
var body = [];
res.on('data', (chunk) => {
body.push(chunk);
}).on('end', () => {
body = Buffer.concat(body).toString();
resolve(body);
}).on('error', (err) => {
reject(err);
});
});
});
}
function combine(inputs) {
var combined = [];
for (i=0; i < inputs.length; i++) {
total += callAPI(inputs[i]['id']);
.then(result => {
combined.push(result);
});
};
var total = combined.reduce((a, b) => a + b, 0);
console.log(total);
// call some function, foo(total, [...args])
}
这似乎让我走到了一半。如果我在then() 块内console.log(combined),我可以看到列表由API 调用的结果组成。但是,我仍然无法在for 循环的“结束”处访问完整的combined。我可以在构建完整列表后将回调附加到要运行的内容吗?有没有更好的办法?
编辑 2(我的解决方案 - 根据 Patrick Roberts 的建议)
function callAPI(id) {
return Promise((resolve, reject) => {
var options = {
host: 'example.com',
path: '/q/result/'.concat(id)
}
var req = http.get(options, (res) => {
var body = [];
res.on('data', (chunk) => {
body.push(chunk);
}).on('end', () => {
body = parseInt(Buffer.concat(body));
resolve(body);
}).on('error', (err) => {
reject(err);
});
});
});
}
function combine(inputs) {
var combined = [];
Promise.all(inputs.map(input => callAPI(input.id)))
.then((combined) => {
var total = combined.reduce((a, b) => a + b, 0);
// foo(total, [...args])
});
};
【问题讨论】:
-
试试这个stackoverflow.com/questions/44636542/… 这正是你要找的。span>
标签: javascript node.js