node.js - 在 Node.js 中等待多个回调的惯用方式

标签 node.js

假设您需要执行一些依赖于某个临时文件的操作。自从 我们在这里谈论的是 Node,这些操作显然是异步的。 等待所有操作完成以完成的惯用方法是什么 知道什么时候可以删除临时文件吗?

这是一些显示我想要做的代码:

do_something(tmp_file_name, function(err) {});
do_something_other(tmp_file_name, function(err) {});
fs.unlink(tmp_file_name);

但是如果我这样写的话,第三个调用可以在前两个之前执行 有机会使用该文件。我需要一些方法来保证前两个 在没有嵌套的情况下继续调用之前已经完成的调用(调用了它们的回调) 调用(并在实践中使它们同步)。

我想过在回调中使用事件发射器并注册一个计数器 作为接收者。计数器将接收完成的事件并计算有多少 行动仍在进行中。当最后一个完成时,它将删除 文件。但是存在竞争条件的风险,我不确定这是 通常这些东西是怎么做的。

Node 人是如何解决这类问题的?

最佳答案

更新:

现在我建议看看:

  • Promises

    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/

相关文章:

node.js - Docker-compose 部署 redis 但 app.js 拒绝连接

node.js - 如何获取React和ReactDOM的ES6模块?

javascript - Mongoose 获取字段总和

node.js - 如何检查元素是否不存在 selenium nodejs

node.js - 当没有任何更改时,Sequelize 关联/模型突然无法识别,模糊错误无法读取未定义的属性 'field'

node.js - Watson NarrowBand Speech to Text 不接受 ogg 文件

node.js - Sequelize 不存储额外的连接表字段

javascript - 使用 nightwatch.js 断言 webelements 列表的文本值

javascript - 从 api 获取的数据未显示

javascript - 413 有效载荷太大,在 express 中调整大小后用于 base64 字符串