[英]node.js: how to implement a routing method with an async call inside a forEach loop?
I have to implement a logic like this: 我必须实现这样的逻辑:
var express = require('express'),
request = require('request');
var array = [
{ url: 'http://www.example1.com' },
{ url: 'http://www.example2.com' },
];
express.Router().get('/job', function (req, res) {
results = [];
array.forEach(function (item) {
request(item.url, function (error, response, body) {
if (!error && response.statusCode == 200) {
results.push(body);
}
});
res.json(results); // <== wrong, results array is empty, here...
});
How do I call res.json(results) being sure forEach loop is ended? 我如何调用res.json(results)以确保forEach循环结束?
UPDATE : it is not a duplicate of suggested answer! 更新 :它不是建议答案的重复!
I need to res.json() when all requests are completed, and not when forEach loop is finished... :-( 当所有请求完成时,而不是在forEach循环完成时,我需要使用res.json()。:-(
A simple way to accomplish this: 一种简单的方法来完成此操作:
var express = require('express'),
request = require('request');
var array = [
{ url: 'http://www.example1.com' },
{ url: 'http://www.example2.com' },
];
//store number of completed calls
var completed = 0;
express.Router().get('/job', function (req, res) {
results = [];
array.forEach(function (item) {
request(item.url, function (error, response, body) {
if (!error && response.statusCode == 200) {
results.push(body);
completed = completed + 1; //iterate counter
onComplete(); //attempt completion
}
});
function onComplete(){
if(completed != array.length) {
return;
}
res.json(results);
// ... rest of code that relies on results
};
});
You can use asnyc
series
to achieve this. 您可以使用
asnyc
series
来实现此目的。 Something like this: 像这样:
var express = require('express'),
request = require('request');
async = require('async);
... ...
async.series([
function(callback) {
request('http://www.example1.com', function (error, response, body) {
if (!error && response.statusCode == 200) {
callback(null, body);
}
});
},
function(callback) {
request('http://www.example2.com', function (error, response, body) {
if (!error && response.statusCode == 200) {
callback(null, body);
}
});
}
], function(err, res) {
res.json(res);
});
You should use promises! 您应该使用诺言! (This example works with last version of node because supports native promises)
(此示例适用于最新版本的节点,因为它支持本机承诺)
var arrayPromises = [];
array.forEach(function (item) {
arrayPromises.push(new Promise(function(resolve, reject) {
request(item.url, function (error, response, body) {
if (!error && response.statusCode == 200) {
resolve(body);
}else{
resolve();
}
});
}));
});
Promise.all(arrayPromises).then(function(results){
res.json(results);
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.