仍然没有理解NodeJs异步函数

时间:2016-02-27 18:42:19

标签: node.js asynchronous

我仍然不了解异步代码如何工作或在NodeJS中创建。见下面的代码和输出。

代码:

var async = require('simple-asyncify');


function calc(){
    n1 = Math.round(Math.random() * (100 - 1) + 1);
    n2 = Math.round(Math.random() * (100 - 1) + 1);
    n3 = n1*n2;
    // console.log(n3);
    return n3;
}


function longRun(id)
{
    console.log("start long run: "+ id);

    for(i=0; i<100000000; i++){
        calc();
    }

    console.log("end long run: " + id);
}    

longRunAsync = async(longRun);


console.log("before");
longRunAsync(1, function(){});
longRunAsync(2, function(){});
longRunAsync(3, function(){});
console.log("after");

输出:

before
after
start long run: 1
end long run: 1
start long run: 2
end long run: 2
start long run: 3
end long run: 3

没有线

longRunAsync = async(longRun);

使用原始函数longRun vs longRunSync,输出为:

before
start long run: 1
end long run: 1
start long run: 2
end long run: 2
start long run: 3
end long run: 3
after

显然,某些东西是异步运行但不是我预期的方式。它看起来像所有的同步代码然后回转并执行应该以同步方式异步的函数。

为什么输出不像下面那样,我怎么能让它像这样执行:

before
start long run: 1
start long run: 2
start long run: 3
after
end long run: 1
end long run: 2
end long run: 3

我想你明白了,我希望每次调用longRunAsync都可以异步运行。

1 个答案:

答案 0 :(得分:1)

你真的没有使用那种&#39; simple-asyncify&#39;库正确。您应该处理由包装函数返回的回调...

longRunAsync(1, function(){});

获取所需的同步行为。

我想这必须是某种学习练习,因为函数的非包装版本会给你很合理的行为。要获得所需的输出,你需要重写你的longRunAsync函数(你需要返回id):

function longRun(id)
{
    console.log("start long run: "+ id);

    for(i=0; i<100000000; i++){
        calc();
    }

    return id
}   

并将其放置在包装函数的回调中:

console.log("before");
longRunAsync(1, function(err, id){
    console.log("end long run: " + id);});
longRunAsync(2, function(){ 
    console.log("end long run: " + id)});
longRunAsync(3, function(){
   console.log("end long run: " + id)\});
console.log("after");

这可能会给你你想要的东西,虽然它有点不确定。那些longRunAsync不保证以任何特定顺序完成。

之前,其中任何一个都可能完成
 console.log("after"); 

所以你的输出看起来像这样:

before
start long run: 1
start long run: 2
start long run: 3
end long run: 1
after
end long run: 2
end long run: 3

如果你希望你的异步函数以某种顺序执行,你必须嵌套它们(也就是回调地狱)或使用类似https://github.com/caolan/async的东西。

以下是嵌套的外观(未经测试)。但我无法弄清楚如何获得console.log(&#39;之后&#39;)打印出你想要的地方。

console.log("before");
longRunAsync(1, function(err, id){
    console.log("end long run: " + id);
    longRunAsync(2, function(){ 
            console.log("end long run: " + id);
            longRunAsync(3, function(){
                    console.log("end long run: " + id)\});});});