Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/438.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 保证所有异步操作_Javascript_Asynchronous_Promise_Bluebird - Fatal编程技术网

Javascript 保证所有异步操作

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在两次完成后都完成了…)。 我知道,在双方都完成(解决)

我有两个异步操作,它们的执行时间不同

一,。执行一个操作需要1秒时间
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'] 
    });