Javascript 保证所有异步操作
我有两个异步操作,它们的执行时间不同 一,。执行一个操作需要1秒时间Javascript 保证所有异步操作,javascript,asynchronous,promise,bluebird,Javascript,Asynchronous,Promise,Bluebird,我有两个异步操作,它们的执行时间不同 一,。执行一个操作需要1秒时间 2.其他操作需要10分钟 证券交易委员会执行 我想使用promise.all,这两个操作将并行执行(我知道在js中没有多步的概念…) 而且都是在同一个踏板上执行, 当我使用promise all时,我期望op1将在op2之前完成,但这不会发生…知道我在这里遗漏了什么吗? (假设op1在我的服务器中保存一些小的内容(1秒)op2(10秒),当我在1秒后检查时,我看不到op1在两次完成后都完成了…)。 我知道,在双方都完成(解决)
2.其他操作需要10分钟 证券交易委员会执行 我想使用promise.all,这两个操作将并行执行(我知道在js中没有多步的概念…) 而且都是在同一个踏板上执行, 当我使用promise all时,我期望op1将在op2之前完成,但这不会发生…知道我在这里遗漏了什么吗? (假设op1在我的服务器中保存一些小的内容(1秒)op2(10秒),当我在1秒后检查时,我看不到op1在两次完成后都完成了…)。 我知道,在双方都完成(解决)后,所有承诺都将完成 我想用承诺。所有这两个操作将并行执行 请注意,使用
Promise.all
与操作是否并行执行无关。它所做的只是给你一个承诺,当两个操作都成功时,这个承诺就会得到解决;当两个操作都失败时,这个承诺就会被拒绝
让我们看看您的代码,请参阅注释:
Promise.all([op1, op2]).then(values => {
// This will happen when BOTH op1 and op2 are done
console.log(values);
}, reason => {
// This will happen when EITHER op1 OR op2 fails
console.log(reason);
});
因此,如果op1
需要1秒,op2
需要10秒,并且我们假设它们都成功,那么您的回调将在10秒后执行(当op2
完成时)。如果您知道op1
只需要一秒钟,那么很可能op1
在您的承诺之前几秒钟就完成了。所有的回调都被调用了
如果希望在op1
完成时收到通知,请使用上的然后打开op1
。您可以单独执行此操作,也可以同时使用Promise.all
在两者都完成时获取通知
此示例使用setTimeout
模拟操作,可能有助于您理解;在下图中,op1
需要100毫秒,op2
需要1000毫秒。为简单起见,它假设两个操作都成功:
var start=Date.now();
var op1=startOp1();
var op2=startOp2();
op1.then(函数(){
//在op1成功时激发;不关心op2
log(“op1在”+(Date.now()-start)+“ms”之后完成”;
});
op2.then(函数(){
//在op2成功时激发;不关心op1
log(“op2在”+(Date.now()-start)+“ms”之后完成”;
});
Promise.all([op1,op2]),然后(function(){
//当两次行动都成功时触发
log(“都在”+(Date.now()-start)+“ms”之后完成”;
});
函数startOp1(){
返回新承诺(函数(解析){
setTimeout(函数(){
解决();
}, 100);
});
}
函数startOp2(标志){
返回新承诺(函数(解析){
setTimeout(函数(){
解决();
}, 1000);
});
}
当我使用promise all时,我希望op1将在op2之前完成,而op2>不会发生…知道我在这里遗漏了什么吗
只有在成功解析所有承诺之后,数组块内的所有单个承诺才会异步执行并到达.then()
尝试在op1和op2的计时器函数和解析函数之间分别使用console.log('op1 done')和console.log('op2 done')。控制台上显示的输出为:
op1 done //after 1 sec
op2 done //after 10 sec
['op1 done','op1 done'] //immediately follows the above one
这应该让您相信异步的本质。还让我再举一个明显的例子,在下面的代码中,从浏览器中保存一个文本,承诺p2在承诺p1之前完成。在5分钟(p1)的时间段内;文件(使用p2)将在执行之前保存在系统中。然后()执行
对于要在op2之前完成的op1,可以使用以下选项之一-
1.承诺链解释
2.ES6中提供的发电机。
3.ES7中提供了异步等待
因为Promise.all()确保了并行执行,而不是一个接一个地执行。您如何知道op1在op2之前完成?能否提供op1
和op2
的代码?Promise.all()在数组中的所有承诺(例如op1
和op2
)完成(已解决/已拒绝)之前不会解析。只有在两者都完成后,才会承诺。all()解析并执行中的代码。然后()
“哪种情况不会发生”-请显示您的实际代码并告诉我们什么情况不会发生“当我在1秒后检查时,我看不到op1完成”-您不应该在某个超时后“检查”,如果要等待该操作,请使用op1。然后(…)
“我想使用promise。所有这两个操作都将并行执行”请注意,使用promise.all与操作是否并行执行无关。它所做的只是给你一个承诺,当其中一个操作失败或两个操作都成功时,这个承诺就会实现。@JennyM Yes<无论是在op1()中使用,code>op1()
都将起相同的作用。然后(…)
或承诺。所有([op1(),…])
上下文或其他地方。“因此,如果op1需要1秒,而op2需要10秒…”…其中一个或两个正在阻塞,那么回调可能会在11秒后执行…:)@deceze:OP说它们都是异步的,我认为这意味着它们不会阻塞JavaScript线程。但是,是的,如果他们所做的事情的性质意味着他们最终会被序列化(即使在JavaScript线程之外,他们都试图对同一个互斥的事情进行操作),那么他们自然会堆积起来。那么这两个操作何时开始呢,我问它,因为promise all中没有多个步骤…?它如何确定在数组中启动哪个promise?@JennyM:promise。all
对启动进程绝对没有任何作用;当您将他们的承诺传递到Promise.all
时,他们已经开始了。它们是由您为获得这些承诺而调用的任何东西启动的(startOp1
和startOp2
),谢谢,但这让人困惑,因为我将它们放在数组中,直到
op1 done //after 1 sec
op2 done //after 10 sec
['op1 done','op1 done'] //immediately follows the above one
var FileSaver = require('file-saver');
var p1 = new Promise((resolve, reject) => {
setTimeout(resolve, 5 * 60 * 1000, 'Executed Promise p2');
// 5 min timer
});
var p2 = new Promise((resolve, reject) => {
var blob = new Blob(["Hello, world!"],
{type:"text/plain;charset=utf-8"});
FileSaver.saveAs(blob
, "hello world.txt");
// Not tested it; from page: https://github.com/eligrey/FileSaver.js/
console.log('done with Promise p1');
resolve('Executed Promise p1')
});
Promise.all([p1, p2]).then(values => {
console.log(values); // ['Executed Promise p1','Executed Promise p2']
});