仍然不理解NodeJs的asynchronous函数
我仍然不理解asynchronous代码如何工作或在NodeJS中创build。 看下面的代码和输出。
码:
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
所以显然有些东西是asynchronous运行,但不是我所期望的。 它看起来像所有的同步代码然后摆动回来,做同步的方式应该是asynchronous的function。
为什么输出不像下面那样,我怎么才能让它像这样执行:
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的每次调用能够asynchronous地运行。
你真的没有正确使用这个“简单asynchronous”库。 你应该处理你的包装函数返回的callback…
longRunAsync(1, function(){});
获得你想要的assync行为。
我想这一定是某种学习练习,因为非包装版本的function给你非常合理的行为。 为了得到你想要的输出,你需要重写你的longRunAsync函数(你需要返回id):
function longRun(id) { console.log("start long run: "+ id); for(i=0; i<100000000; i++){ calc(); } return id }
并把它放在包装函数的callback中:
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
如果你想让asynchronous函数以某种顺序执行,你必须将它们嵌套(又名callback地狱)或者使用类似https://github.com/caolan/async的东西。
以下是嵌套的外观(未testing)。 但我不知道如何让console.log('之后')打印出你想要的地方。
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)\});});});