假设您需要执行一些依赖于某个临时文件的操作。自从 我们在这里谈论的是 Node,这些操作显然是异步的。 等待所有操作完成以完成的惯用方法是什么 知道什么时候可以删除临时文件吗?
这是一些显示我想要做的代码:
do_something(tmp_file_name, function(err) {});
do_something_other(tmp_file_name, function(err) {});
fs.unlink(tmp_file_name);
但是如果我这样写的话,第三个调用可以在前两个之前执行 有机会使用该文件。我需要一些方法来保证前两个 在没有嵌套的情况下继续调用之前已经完成的调用(调用了它们的回调) 调用(并在实践中使它们同步)。
我想过在回调中使用事件发射器并注册一个计数器 作为接收者。计数器将接收完成的事件并计算有多少 行动仍在进行中。当最后一个完成时,它将删除 文件。但是存在竞争条件的风险,我不确定这是 通常这些东西是怎么做的。
Node 人是如何解决这类问题的?
最佳答案
更新:
现在我建议看看:
-
The Promise object is used for deferred and asynchronous computations. A Promise represents an operation that hasn't completed yet, but is expected in the future.
一个流行的 Promise 库是 bluebird . A 会建议看看 why promises .
You should use promises to turn this:
fs.readFile("file.json", function (err, val) { if (err) { console.error("unable to read file"); } else { try { val = JSON.parse(val); console.log(val.success); } catch (e) { console.error("invalid json in file"); } } });
Into this:
fs.readFileAsync("file.json").then(JSON.parse).then(function (val) { console.log(val.success); }) .catch(SyntaxError, function (e) { console.error("invalid json in file"); }) .catch(function (e) { console.error("unable to read file"); });
生成器: 例如通过 co .
Generator based control flow goodness for nodejs and the browser, using promises, letting you write non-blocking code in a nice-ish way.
var co = require('co'); co(function *(){ // yield any promise var result = yield Promise.resolve(true); }).catch(onerror); co(function *(){ // resolve multiple promises in parallel var a = Promise.resolve(1); var b = Promise.resolve(2); var c = Promise.resolve(3); var res = yield [a, b, c]; console.log(res); // => [1, 2, 3] }).catch(onerror); // errors can be try/catched co(function *(){ try { yield Promise.reject(new Error('boom')); } catch (err) { console.error(err.message); // "boom" } }).catch(onerror); function onerror(err) { // log any uncaught errors // co will not throw any errors you do not handle!!! // HANDLE ALL YOUR ERRORS!!! console.error(err.stack); }
如果我理解正确我认为你应该看看很好的async图书馆。你应该特别看看series .只是来自 github 页面的片段的副本:
async.series([
function(callback){
// do some stuff ...
callback(null, 'one');
},
function(callback){
// do some more stuff ...
callback(null, 'two');
},
],
// optional callback
function(err, results){
// results is now equal to ['one', 'two']
});
// an example using an object instead of an array
async.series({
one: function(callback){
setTimeout(function(){
callback(null, 1);
}, 200);
},
two: function(callback){
setTimeout(function(){
callback(null, 2);
}, 100);
},
},
function(err, results) {
// results is now equals to: {one: 1, two: 2}
});
另外,这个库也可以在浏览器中运行。
关于node.js - 在 Node.js 中等待多个回调的惯用方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5172244/