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

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

本文介绍了在Node.js中等待多个回调的惯用方式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Suppose you need to do some operations that depend on some temp file. Sincewe're talking about Node here, those operations are obviously asynchronous.What is the idiomatic way to wait for all operations to finish in order toknow when the temp file can be deleted?

这是一些代码,显示我想做什么:

Here is some code showing what I want to do:

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

但是如果我这样写的话,第三个调用可以在前两个调用之前执行有机会使用该文件.我需要某种方式来保证前两个在不嵌套的情况下继续进行调用(已调用其回调)通话(并在实际中使其同步).

But if I write it this way, the third call can be executed before the first twoget a chance to use the file. I need some way to guarantee that the first twocalls already finished (invoked their callbacks) before moving on without nestingthe calls (and making them synchronous in practice).

我考虑过在回调中使用事件发射器并注册一个计数器作为接收者.计数器将接收完成的事件并计数多少操作仍在进行中.最后一个完成后,它将删除文件.但是存在比赛条件的风险,我不确定这是通常是怎么做的.

I thought about using event emitters on the callbacks and registering a counteras receiver. The counter would receive the finished events and count how manyoperations were still pending. When the last one finished, it would delete thefile. But there is the risk of a race condition and I'm not sure this isusually how this stuff is done.

Node人员如何解决此类问题?

How do Node people solve this kind of problem?

推荐答案

更新:

现在,我建议看看:

  • Promises

一个流行的Promise库是 bluebird . A建议您查看为什么要承诺.

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

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.

    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.

    这篇关于在Node.js中等待多个回调的惯用方式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

    08-16 07:03