如何阻止一个function,直到前一个完成? 的NodeJS

有一个for循环dynamic值可能是从小到大,我想确保一个调用search完成,然后下一个可以开始。 我怎么做? 我读过process.nextTick和setImmediate,但我不确定如何在这种情况下使用。

function search(x) { dns.resolve(x, function (err, addresses) { if (!err) { res.send("bad"); } else { res.send("good"); } }); } for(a = 0; a < queries.length; a++) { query = queries[a]; search(query); } 

我通常只是使用事件发射器来实现同步,所以我仍然可以在asynchronous环境的思维模式下工作。 在我的代码下面,每当​​一个DNSparsing完成,它会产生一个事件,这个事件被search函数监听,并让它知道发起一个新的search。 另外,您将学习如何创build自己的事件发射器,这非常棒。

如果要使其对于特定大小的域名数组asynchronous,可以创build一个分母variables,并使用模块运算符以块的forms发送asynchronous,并且每当模数到达时仅触发同步事件(清除asynchronous缓冲区) 0。

 // program that uses event emitters to create sync code in an async env var dns = require('dns') //dns from core var eventEmitter = require('events').EventEmitter //Event Emitter from core var ee = new eventEmitter; //make an Event Emitter object var queries = ['yahoo.com','google.com','james.com']; ee.on('next', next_search); //create a listener for an event we define // our listening function that executes on our defined 'next' event function next_search() { search(queries[a]); if(queries.length == a) process.exit(0); ++a; } // the actual search function that uses DNS function search(x) { dns.resolve(x, function (err) { if (!err) { //res.send("bad"); console.log('bad: ' + x) ee.emit('next') } else { //res.send("good"); console.log('good: ' + x) ee.emit('next') } }); } // global variable to keep track of our name queue length var a = 0; // kick it all off next_search() 

有几个库可以帮助你组织执行asynchronous代码。 asynchronous是我使用的,它是eachSeries()在这里很有用:

 function search(x,callback) { dns.resolve(x, function (err, addresses) { if (!err) { res.send("bad"); } else { res.send("good"); } callback(err); }); } async.eachSeries(queries, function(query,callback) { search(query,callback); }, function(err) { if(err) { console.log("we had an error"); } } ); 

请注意,只要有一个迭代发生错误,Async就会调用最后一个callback函数,所以如果你不想停下来,你需要在search()callback(err) search()而不是callback(err)

更新(不使用库):

如果你不想使用库,你可以像这样自己实现:

 function searchInternal(queries, idx, callback) { if(idx === queries.length) { callback(); return; } dns.resolve(queries[idx], function (err, addresses) { if (!err) { res.send("bad"); } else { res.send("good"); } searchInternal(queries, idx+1, callback); }); } function searchAll(queries, callback) { searchInternal(queries, 0, callback); } searchAll(queries, function() { console.log("all done now"); }); 

请注意,这个代码没有经过testing,可能不是最好的实现,但这就是为什么我们使用库。

我最近创build了一个叫wait.for的简单抽象,以同步模式调用asynchronous函数(基于节点光纤)。 它是在:

https://github.com/luciotato/waitfor

使用wait.for ,你可以调用dns.resolve来顺序执行。

wait.for允许你调用任何标准的nodejsasynchronous函数,就好像它是一个同步函数,而不会阻塞节点的事件循环。 您可以在需要时顺序编码。

使用wait.for你的代码将是:

 for(a = 0; a < queries.length; a++) { try { addresses = wait.for(dns.resolve,queries[a]); res.send('good'); } catch(err){ res.send('bad'); } }//end for