且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

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

更新时间:2022-06-17 08:32:18

更新:

现在,我建议看看:

  • Promises

Promise对象用于延迟和异步计算. Promise表示尚未完成的操作,但是 预计在未来.

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建议您查看为什么要承诺.

A popular promises library is bluebird. A would advise to have a look at why promises.

您应该使用promise来解决这个问题:

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

对此:

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 .

  • generators: For example via co.

    针对Node.js和浏览器的基于生成器的控制流优势, 使用Promise,可以让您以一种不错的方式编写非阻塞代码.

    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 库.您尤其应该看一下系列.只是github页面片段中的一个副本:

    If I understand correctly I think you should have a look at the very good async library. You should especially have a look at the series. Just a copy from the snippets from github page:

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

    此外,该库还可以在浏览器中运行.

    As a plus this library can also run in the browser.