Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/461.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_Concurrency_Promise - Fatal编程技术网

Javascript 一个同步进程和一个异步进程的组合是否同时运行?

Javascript 一个同步进程和一个异步进程的组合是否同时运行?,javascript,concurrency,promise,Javascript,Concurrency,Promise,请您告诉我,这段代码末尾列出的结果是否意味着承诺p5()和f5()正在同时处理 在我的项目代码中,sync()生成并返回一个文档片段来替换DOM中的节点,但不替换它,p5()是一个indexedDB数据库读写操作。除非数据库操作成功,否则我不想用新片段替换现有节点,我想根据p5()或f5()可能失败的原因提供用户选项 我想知道是否将同步函数sync()放在承诺中,这样它就可以放在promise.allselled中,从而允许这两个进程同时运行,然后在两者都解决后检查错误,而不是等待p5()在sy

请您告诉我,这段代码末尾列出的结果是否意味着承诺
p5()
f5()
正在同时处理

在我的项目代码中,
sync()
生成并返回一个文档片段来替换DOM中的节点,但不替换它,
p5()
是一个indexedDB数据库读写操作。除非数据库操作成功,否则我不想用新片段替换现有节点,我想根据
p5()
f5()
可能失败的原因提供用户选项

我想知道是否将同步函数
sync()
放在承诺中,这样它就可以放在
promise.allselled
中,从而允许这两个进程同时运行,然后在两者都解决后检查错误,而不是等待
p5()
sync()
中开始构建片段之前完成

我对并发性知之甚少,但这些结果似乎表明,
sync()
f5()
花了两秒钟完成,在
p5()
之前花了三秒钟完成,所有问题都在五秒钟内解决,而不是总共花了七秒钟

多谢各位

函数p5(){
返回新承诺((解决、拒绝)=>{
setTimeout(()=>resolve('p5 resolved at:'+new Date()),5000);})
函数f5(){
返回新承诺((解决、拒绝)=>{
请尝试{解析(sync());}
捕获(e){拒绝(e)}
}); }
函数sync(){
让我,str='';
对于(i=0;i<50000000;i++)str=str+'一个文本字符串';
i=str=null;
返回“同步完成时间:”+新日期();
}
log('start:'+newdate());
Promise.allSettled([p5(),f5()]),然后((r)=>{console.log(r[0]);console.log(r[1]);});
/*结果:
开始时间:星期六2020年2月22日00:36:53 GMT-0500(东部标准时间)
r[0]:
{“状态”:“已完成”,
“值”:“p5解析时间:星期六2020年2月22日00:36:58 GMT-0500(东部标准时间)”}
r[1]:
{“状态”:“已完成”,
“值”:“同步完成时间:星期六2020年2月22日00:36:55 GMT-0500(东部标准时间)”}

*/
因为您首先调用了实际的异步操作
p5()
,它将在同步操作
f5()
运行时启动并在后台运行

异步
p5()
在同步代码完成之前无法处理其完成,因为主JS线程一次只能做一件事,而同步代码正在阻塞事件循环,因此在同步
f5()
完成之前,无法处理任何异步操作的完成事件

如果将代码切换为重新排序
p5()
f5()
,如下所示:

 Promise.allSettled( [ f5(), p5() ] ).then(...)
然后,就不会有并发,因为在
f5()
完成之前,
p5()
甚至都不会启动

我想知道,如果将同步函数
sync()
放在一个承诺中,这样就可以将它放在一个承诺中。allSettled将允许这两个进程同时运行,然后在两者都解决后检查错误,而不是等到p5()完成后才开始在
sync()
中构建片段


仅供参考,将对
sync()
的调用包装在承诺中并没有真正的好处。你也可以这样做:

p5().then(...);
f5();
这将使您获得相同的总体执行时间,直到两者都完成,因为
p5()
仍然首先启动并在后台运行,并且在阻塞
f5()
完成之前无法处理其完成事件


另外,您应该知道,您不必在承诺中包装
sync()
。您可以将普通值传递给
Promise.all()
Promise.allsolited()
。所以,你也可以这样做:

Promise.allSettled([p5(), sync()]).then(...)

而且,它也会起同样的作用。

谢谢您的解释。我可以再问一个问题吗?如果您不将
sync()
包装在承诺中,并且希望捕获函数中多个代码部分中的潜在错误以指示错误的位置,那么除了从
catch
中使用
return
之外,还有其他方法返回自定义错误消息吗。我之所以这样问,是因为即使返回错误,
状态
似乎也将始终得到满足。谢谢。@Gary-如果
sync
可以同步抛出,那么将其封装在承诺中可能会有所帮助,这样您就可以更容易地将其完成捕获为一个被拒绝的承诺,并完成
p5()
。如果您想捕获
sync()
中的异常并将其转换为返回的错误(而不是异常),那么您只需
返回一些可检测的错误值(通常是
错误
对象或
错误
对象的子类),这是正确的。