Idiomatic way to wait for multiple callbacks in Node.js

前端 未结 8 2246
旧巷少年郎
旧巷少年郎 2020-11-28 04:12

Suppose you need to do some operations that depend on some temp file. Since we\'re talking about Node here, those operations are obviously asynchronous. What is the idiomati

8条回答
  •  广开言路
    2020-11-28 04:24

    Update:

    Now I would advise to have a look at:

    • 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.

      A popular promises library is bluebird. A would advise to have a look at 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");
      });
      
    • generators: For example via 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);
      }
      

    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.

提交回复
热议问题