2016-02-27 95 views
1

我仍然不理解异步代码是如何工作的或者是在NodeJS中创建的。请参阅下面的代码和输出。仍然不了解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); 

而使用原始的功能龙润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的每次调用运行良好,异步。

+0

我不知道那个图书馆,但如果你开始了,我会建议你直接承诺 - 例如, https://开头github上。com/petkaantonov/bluebird –

+1

你的longRun函数是同步的,这就是为什么它完成它的工作,然后调用第二个longRun。 – Edgar

+0

我建议你先阅读[doc for simple-asyncify](https://github.com/lydell/simple-asyncify),然后提出一个更具体的问题,说明你为什么会看到某些特定的行为。简单异化中没有魔力。它不会以某种方式在后台运行同步操作。它只是推迟运行它,直到当前事件循环操作结束。而且,您必须将回调传递给您的异步函数,以便了解何时完成或得到结果。请阅读asyncify文件,如果你真的打算使用它。 – jfriend00

回答

1

你真的没有正确使用那个'simple-asyncify'库。您应该处理您的包装函数返回的回调...

longRunAsync(1, function(){}); 

以获得您想要的assync行为。

我想这肯定是某种学习练习,因为非包装版本的功能给你非常合理的行为。为了得到你想要的输出,你会重写你的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"); 

完整,所以您的输出可能是这个样子:如果你想YOUT异步功能在某种顺序执行

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('after')打印出你想要的地方。

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)\});});});