node.js里的forEach也是异步的吗
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了node.js里的forEach也是异步的吗相关的知识,希望对你有一定的参考价值。
参考技术A 你好,js是同步执行的,一个简单示例解释, for(var i = 0;i < 10;i++) console.log(i)for(var i = 10;i < 20;i++) console.log(i)以上两个for循环,第一个打印1-10,第二个打印10-20,结果是1-20按顺序输出 js中代码是同步执行的,只有在ajax的...node.js:如何在 forEach 循环中使用异步调用实现路由方法?
【中文标题】node.js:如何在 forEach 循环中使用异步调用实现路由方法?【英文标题】:node.js: how to implement a routing method with an async call inside a forEach loop? 【发布时间】:2015-12-11 23:41:29 【问题描述】:我必须实现这样的逻辑:
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...
);
如何调用 res.json(results) 以确保 forEach 循环已结束?
更新:它不是建议答案的重复!
当所有请求完成时我需要 res.json(),而当 forEach 循环完成时 not... :-(
【问题讨论】:
Callback after ForEach is done. 的可能重复项forEach
已完成。不是异步的request()
函数。
查看我的更新... :-(
【参考方案1】:
您可以使用asnyc
series
来实现此目的。像这样的:
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);
);
【讨论】:
在现实生活中,我没有 2 个请求,但有数千个...... :-( 我不认为等待数千个请求完成是个好主意。也许你应该改变你的逻辑并寻找一个后台进程来处理它们? 好点!在哪里可以找到有关将节点作为后台进程运行的一些信息? 这里有一篇好文章:andygup.net/node-js-moving-intensive-tasks-to-a-child-process 谢谢...我想我不会采用建议的方法:我只会将节点进程作为 cron 作业运行;进程状态将在数据库上共享...【参考方案2】:实现此目的的简单方法:
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
;
);
【讨论】:
【参考方案3】:你应该使用承诺! (此示例适用于最新版本的节点,因为支持原生承诺)
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);
);
【讨论】:
以上是关于node.js里的forEach也是异步的吗的主要内容,如果未能解决你的问题,请参考以下文章