我正在使用快递应用。我希望为我想要运行的一系列函数提供并行流。我正在考虑使用async模块。
我想知道是否还有其他模块比这更好?
其次我想知道这些函数是否必须是异步的?假设我有这样的代码
var sum = function(x, y){
return (x + y)
}
async.parallel([
function(callback){
setTimeout(function(){
result = sum (x, y); //just an example for a synchronous function
callback(null, result);
}, 100);
},
function(callback){
result = sum (x, y); //just an example for a synchronous function
callback(null, result);
}
],
// optional callback
function(err, results){
console.log(result);
// the results array will equal ['one','two'] even though
// the second function had a shorter timeout.
});
所以你可以在里面找到同步的功能。那么这两个还是会并行运行吗?
我还听说在node.js中,只有I / O任务可以并行运行,因为node.js是单线程的。这是真的吗?所以如果我没有在异步模块中的I / O任务,它们也不会并行运行而只是出现?
请帮忙。
答案 0 :(得分:2)
Node.js 单线程和(开箱即用)单核。
因此,Node.js中没有真正并行,因为它是单线程的。
只有当您的任务包含异步代码时,async.parallel
方法才有用:它将等待所有响应,然后执行回调中的代码。
但,如果您的任务仅包含同步代码,则结果将是同步的。
所以你最后一个问题的答案是是。
如果您想尝试其他控制流模块,请尝试Q。它实现了Javascript Promises,使异步代码更易于阅读和组织。
如果您想真正并行化您的任务,请查看child process或cluster module。
还有一些特殊的本机模块Threads à gogo实现了线程化。
代码的完整示例:
var async = require('async');
sum = function(x, y) {
return (x + y)
}
x = 2;
y = 3;
async.parallel([
function(callback) {
setTimeout(function() {
result = sum(x, y);
console.log('f1');
callback(null, result);
}, 100);
},
function(callback) {
result = sum(x, y);
console.log('f2');
callback(null, result);
}
],
function(err, results) {
console.log(result);
}
);
如果运行这段代码,输出结果将始终为:f2, f1, 5
。这是因为第一个函数中有setTimeout
,但执行代码的方式是同步。
如果您想要被说服,请在第一个函数中删除setTimeout,并看到输出始终为f1, f2, 5
。
所以:
async.parallel非常有用,如果你想同时运行两个HTTP请求(它们是异步的),并等待它们都完成。
如果在其中放入同步代码,则async.parallel没有用,因为代码将以同步方式执行。
答案 1 :(得分:1)
async是这类任务的事实上的模块,请继续使用。
不,这些功能不是必须异步的。我相信你的所有问题都可以通过以下方式回答:http://blog.mixu.net/2011/02/01/understanding-the-node-js-event-loop/,其中以下是重点:
Node.js为您的代码保留一个线程,然而一切都在运行 并行,除了你的代码。
答案 2 :(得分:0)
另一种方法是使用promise(bluebird)。 请参阅此处的文档和示例用法http://bluebirdjs.com/docs/getting-started.html)。
如,
function f1() {... }
function f2() {... }
function f3() {... }
Promise.all[f1(), f2(), f3()] // run all functions parallel
.then(() => { /*do something*/})
.catch(err => { /*handle error*/ })