当前位置: 首页 > 面试题库 >

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

甄德寿
2023-03-14
问题内容

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

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

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

但是,如果我这样编写,则可以在前两个调用有机会使用该文件之前执行第三个调用。我需要某种方法来确保前两个调用在结束之前已经完成(调用了它们的回调),而没有嵌套这些调用(并使它们在实践中保持同步)。

我考虑过在回调上使用事件发射器,并将计数器注册为接收器。计数器将接收已完成的事件并计算仍有多少操作待处理。当最后一个完成时,它将删除该文件。但是存在比赛条件的风险,我不确定这通常是如何完成的。

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


问题答案:

更新:

现在,我建议看一下:

  • 承诺

Promise对象用于延迟和异步计算。Promise表示尚未完成的操作,但有望在将来进行。

一个流行的承诺库是蓝鸟。A建议看看为什么答应。

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

>     >     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。

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

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

如果我理解正确,我想您应该看一下非常好的异步库。您应该特别看一下该系列。只是来自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}
    });

另外,该库还可以在浏览器中运行。



 类似资料:
  • 问题内容: 我有一个循环,可以调用API并将结果编译成数组。我如何等待所有调用完成后才能恢复执行?我看到了一系列有关如何等到打完一个电话的答案,但我不知道如何检查所有这些。如果我做一个while循环,一直等到’obj’是正确的长度,则页面只会停顿直到调用完成,这不是我想要的。请帮助? 问题答案: 如果您使用jQuery的deferred,这很容易。有一种方法,等待多个诺言完成,然后运行回调。那就是

  • 问题内容: 我有这样的代码: 我的问题是,节点在运行时立即终止。它显示“ Icanhasclient”,但没有调用回调内的console.log。 (本例中的mysql是node- mysql 。 有什么办法可以使node.js在退出之前等待回调完成? 问题答案: 回调未排队 节点运行直到所有事件 队列 都为空。诸如以下的调用时,回调将添加到事件 队列 中 已执行。该调用是模块开发人员编写的代码的

  • 问题内容: 我有一个在另一个类中启动异步任务,然后应该等待结果。 问题是方法将在方法运行完成后立即完成,对吗? 这意味着,通常,在启动异步任务后,它将立即关闭,并且不再在那里接收结果。 如何使以上代码段正常工作?开始任务后,我已经尝试放入(任意持续时间)。似乎可以正常工作。 但这绝对不是一个干净的解决方案。也许甚至有一些严重的问题。 有更好的解决方案吗? 问题答案: 使用标准类代替,从回调启动异步

  • 问题内容: 我已经审查了很多有关此类问题的答案,但现在我对最佳方法感到困惑。鉴于最新的jquery,我想 调用一个ajax函数 做ajax处理(成功或错误)//正常工作 成功或错误时,将状态返回到调用函数以进行进一步处理 在调用函数(doAjax)中,如何等待回调,然后完成对成功或错误的处理(在这种情况下,成功时清除表格,错误时保持原样) 感谢任何建议, Art [EDIT] 你们发现有一个错字,

  • 问题内容: 当使用简单的回调(例如下面的示例)时: 如何更改功能以使用异步/等待?具体来说,假设“ someEvent”被保证只能被调用一次,那么我希望函数测试是一个异步函数,该异步函数在执行回调之前不会返回,例如: 问题答案: 不是魔术。异步函数是可以为您解开Promises的函数,因此您需要返回一个Promise才能起作用。像这样: 然后 但这也是一个谎言,因为异步函数也返回Promises本

  • 使用以下示例中的简单回调时: 如何将函数更改为使用异步/等待?具体地说,假设某个事件保证被调用一次并且只有一次,我希望函数测试是一个异步函数,直到执行回调才返回,例如: