Javascript 如何确保一组异步函数调用仅在另一组异步函数调用完成后发生?

Javascript 如何确保一组异步函数调用仅在另一组异步函数调用完成后发生?,javascript,node.js,promise,Javascript,Node.js,Promise,我是JavaScript新手,我认为我尝试做的事情可以通过承诺来解决,但在阅读了Mozilla文档后,我无法理解如何实现这一点 让我用下面的代码演示我试图实现的目标 // file demo.js function async_print(message, seconds) { setTimeout(function () { console.log(message, '(' + seconds + ' s)') }, seconds * 1000); } //

我是JavaScript新手,我认为我尝试做的事情可以通过承诺来解决,但在阅读了Mozilla文档后,我无法理解如何实现这一点

让我用下面的代码演示我试图实现的目标

// file demo.js
function async_print(message, seconds)
{
    setTimeout(function () {
        console.log(message, '(' + seconds + ' s)')
    }, seconds * 1000);
}

// First execute the following three asynchronously
async_print('foo', 1)
async_print('foo', 2)
async_print('foo', 3)

// Then execute the following three asynchronously
async_print('bar', 1)
async_print('bar', 2)
async_print('bar', 3)

// Then execute the following three asynchronously
async_print('baz', 1)
async_print('baz', 2)
async_print('baz', 3)
我得到以下输出

$ node demo.js 
foo (1 s)
bar (1 s)
baz (1 s)
foo (2 s)
bar (2 s)
baz (2 s)
foo (3 s)
bar (3 s)
baz (3 s)
另外,请参见此处的JSFIDLE:

我的意图在代码中记录为注释。我想先执行所有的“foo”语句。“bar”语句只能在“foo”语句完成后执行。“baz”语句只能在“bar”语句完成后执行。这意味着输出应该如下所示

foo (1 s)
foo (2 s)
foo (3 s)
bar (1 s)
bar (2 s)
bar (3 s)
baz (1 s)
baz (2 s)
baz (3 s)
这是否可以在JavaScript或node中方便地完成,而不依赖于第三方库?例如,JavaScript能在这里提供帮助吗?我知道我可能必须修改
async\u print
函数签名或将其包装在其他内容上,以便传递可调用的回调以指示函数完成。我同意这样的修改。我基本上需要知道如何完成这样的工作


您能否提供一个完整的代码示例来实现这一点,以便我可以使用它来学习如何在JavaScript中执行这些操作?

这是最适合于承诺、
Promise.all()和承诺链接的。以下是一个片段,您可以在现代浏览器中运行以查看输出:

//从此异步函数返回一个承诺,该承诺在完成时解析
函数异步打印(消息,秒){
返回新承诺(函数(解析){
setTimeout(函数(){
解决();
},秒*1000);
}).然后(函数(){
日志(消息“(“+秒+”秒)”
});
}
所有([异步打印('foo',1),异步打印('foo',2),异步打印('foo',3)])。然后(函数(){
返回承诺。全部([异步打印('bar',1),异步打印('bar',2),异步打印('bar',3)];
}).然后(函数(){
返回承诺。全部([异步打印('baz',1),异步打印('baz',2),异步打印('baz',3)];
}).然后(函数(){
//这里做的一切
});
函数日志(x,y){
var div=document.createElement(“div”);
div.innerHTML=x;
如果(arguments.length>1){
div.innerHTML+=y;
}
文件.正文.附件(div);

}
CPS和promises是实现这一点的两种方法,生成器可以在ES6中提供帮助,异步/等待将来的到来。您应该将
日志(…)
放入
中,然后
回调(而不是promisify-
设置超时
-回调)throw@Bergi-根据建议进行更改。