javascript nodejs:等待其他方法完成后再执行

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18116348/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 10:46:49  来源:igfitidea点击:

nodejs: wait for other methods to finish before executing

javascriptnode.js

提问by yaoxing

say I have 2 methods:

说我有两种方法:

function A(callback) { ... }
function B(callback) { ... }

I want to execute:
function C();
after both A and B are finished.
what we usually do is to put function C in the callback like:

我想执行:
function C();
在 A 和 B 都完成后。
我们通常做的是将函数 C 放在回调中,例如:

A(function() {
  B(function() {
    C();
  });
});

now if both A and B takes a long time, I don't want B to execute after A has been finished. instead I want to start them at the same time to enhance performance.
what I'm thinking is to implement something like a semaphore (not really a semaphore of course), it fires an event after both A and B are finished. so that I can call C from within the event.

现在如果 A 和 B 都需要很长时间,我不希望 B 在 A 完成后执行。相反,我想同时启动它们以提高性能。
我在想的是实现类似信号量的东西(当然不是真正的信号量),它会在 A 和 B 都完成后触发一个事件。这样我就可以从事件中调用 C。

what I want to know is, is there any library implemented the above function already? I believe I'm not the first one who wants to do it.
any help is appreciated.

我想知道的是,是否有任何库已经实现了上述功能?我相信我不是第一个想做这件事的人。
任何帮助表示赞赏。

采纳答案by Jonathan Lonowski

To expand on my comment...

扩展我的评论...

asyncis a commonly usedasynchronous flow control library for Node.js.

async是Node.js常用的异步流控制库。

Its async.parallel()would probably do well for this:

async.parallel()可能会为此做好:

async.parallel([
    function(done) {
        A(function () {
            done(null);
        });
    },

    function(done) {
        B(function () {
            done(null);
        });
    }
], function (err) {
    C();
});

It's possible that this can be shortened, but it depends on how each function interact with callbacks and whether they follow the common Node.js pattern of error-first callbacks:

这可能会被缩短,但这取决于每个函数如何与回调交互以及它们是否遵循error-first 回调的常见 Node.js 模式:

async.parallel([A, B], C);

回答by Rob Raisch

For the sake of completeness and as mentioned above, the same result can be achieved using an external object to hold completion state where both A() and B() check to see if the other has completed and if so, invokes C(). As in:

为了完整起见,如上所述,可以使用外部对象来保持完成状态,其中 A() 和 B() 检查另一个是否已完成,如果是,则调用 C() 来实现相同的结果。如:

var results={};

function onComplete(){
    if(results['A'] && results['B'] && !results['C']) {
        C();
    }
}

function A(){
    // ... 
    results['A']=true;
    onComplete();
}

function B(){
    // ... 
    results['B']=true;
    onComplete();
}

The results object can be replaced by adding a 'isComplete' flag to both A() and B(), as in:

可以通过向 A() 和 B() 添加一个“isComplete”标志来替换结果对象,如下所示:

function A(){
    // ...
    A.isComplete=true;
    onComplete();
}

And modifying onComplete to check this new flag:

并修改 onComplete 以检查这个新标志:

function onComplete(){
    if(A.isComplete && ...
}

Or, the same using events:

或者,同样使用事件:

var util=require('util'),
    events=require('events'),
    EventEmitter=events.EventEmitter;

function F(){
    EventEmitter.call(this); // init ancestor
}

util.inherits(F,EventEmitter); // assign ancestor

F.prototype.A=function(){
    var self=this;
    console.log('running A()');
    setTimeout(function(){ // simulate long running code - 5 seconds
        F.prototype.A.isComplete=true;
        self.emit('complete','A');
    },5000);
};

F.prototype.B=function(){
    var self=this;
    console.log('running B()');
    setTimeout(function(){ // simulate long running code - 3 seconds
        F.prototype.B.isComplete=true;
        self.emit('complete','B');
    },3000);
};

F.prototype.C=function(){
    console.log('running C()');
};

var f=new F;
f.on('complete',function(which){ // onComplete handler
    console.log(which+'() is complete');

    if(F.prototype.A.isComplete && F.prototype.B.isComplete){
        f.C();
    }
});

// start it up
f.A();
f.B();

which, when run, will produce:

运行时,将产生:

>node example.js
running A()
running B()
B() is complete
A() is complete
running C()
>

回答by Muhammad Umer

async.parallel([
    function(){ ... },
    function(){ ... }
], callback);

from: https://github.com/caolan/async

来自:https: //github.com/caolan/async

so in your case:

所以在你的情况下:

async.parallel([funcA,funcB],funcC);

//function definitions
function funcA() {...}
function funcB() {...}
function funcC() {...}

without modules i guess it would look something like this:

如果没有模块,我想它看起来像这样:

var numFuncs = 2;
A(D);
B(D);

and then 
function D() {
if(numFuncs==0){ C(); } else {
numFuncs--; 
}}

or like this:

或者像这样:

A(D(C));
B(D(C));


function D() {
    var x = process.funcsToCall= process.funcsToCall || {};
    var f=arguments[0];
    (!x.hasOwnProperty(f.name))?x[f.name]=0:x[f.name]++;
    return function(){
       (x[f.name]==0)?f():x[f.name]--;
    }
}

回答by Richard Nienaber

If you're running on ES6, you can use Promise.all. Here is the example code rewritten:

如果您在 ES6 上运行,则可以使用Promise.all。这是重写的示例代码:

Promise.all([
  new Promise((resolve) => A(() => resolve())),
  new Promise((resolve) => B(() => resolve())),
]).then(() => {
  C()
}).catch(err => {
  // handle errors from function A, B and C
})

回答by Salahin Rocky

we can ayncand awaitfor this purpose for example:

我们可以为此目的进行ayncawait,例如:

async function Foo(){
   // function logic
}

and this Foo function as:

这个 Foo 函数为:

await Foo();