promise 存到变量中为什么可以防止阻塞?

2020-09-27 16:57:17 +08:00
 siwadiya


为什么将 promise 存到变量中,这三个 promise 就会同时运行,而不是阻塞后面代码的运行

4392 次点击
所在节点    JavaScript
11 条回复
abelmakihara
2020-09-27 17:09:20 +08:00
因为是 await 阻塞在那的
第二个例子是执行完了再一起拿结果的
noe132
2020-09-27 17:15:21 +08:00
因为第一个例子等同于
const timeoutPromise1 = timeoutPromise(3000)
await timeoutPromise1
const timeoutPromise2 = timeoutPromise(3000)
await timeoutPromise2
const timeoutPromise3 = timeoutPromise(3000)
await timeoutPromise3

而第二个例子因为都是等待 3 秒,所以 await timeoutPromise1 时第二个和第三个的时间也到了。
你试试 如果时间不一样会怎么样

const timeoutPromise1 = timeoutPromise(3000)
const timeoutPromise2 = timeoutPromise(4000)
const timeoutPromise3 = timeoutPromise(5000)
await timeoutPromise1
print('promise 1 done')
await timeoutPromise2
print('promise 2 done')
await timeoutPromise3
print('promise 3 done')
Curtion
2020-09-27 17:19:09 +08:00
上面的例子中第一个 timeoutPromise 在 resolve 后才会继续注册第二个 timeoutPromise 微任务;而第二个例子在当前 Event Loop 中就一次性注册了三个微任务。
wxsm
2020-09-27 17:21:18 +08:00
#2 说得很好了。
siwadiya
2020-09-27 17:22:28 +08:00
@abelmakihara 可以这么理解吗: 这三个 promise 是同步运行的,后面的 await 是为了将 pending 更改为 fulfilled
abelmakihara
2020-09-27 17:26:35 +08:00
@siwadiya 当然不是了 是 await 在等待着状态变更的返回结果 因果反了
他们都是'同步'运行了 3s
所以 await 拿结果的时候非常快
不然像#2 的那样
await timeoutPromise2/3 的时候还是需要再各等待 1s 的
Reapper
2020-09-27 17:33:20 +08:00
#2 已经很详细了,第一个例子中是 3s 3s 3s,第二个例子中,先执行了 3 个 promise,然后开始等待,3s 后有结果了,然后输出 输出 输出,async/await 只是一个语法糖,建议理解一下 promise 的执行过程
yzqtdu
2020-09-27 17:59:22 +08:00
个人观点,这里不存在所谓的阻塞,generator 在 yield 之后阻塞了后续命令的执行吗?没有,执行流只是切换到其他栈去了,在合适的时机可以跳回 yield 之后的命令。async/await promise 这些都不阻塞执行流,要说阻塞,同步阻塞 io 或者 sleep 才是真的阻塞吧
SoloCompany
2020-09-27 19:18:26 +08:00
如果希望去掉无意义的返回值

可以用 await Promise.all
Jirajine
2020-09-27 19:25:04 +08:00
因为 js 的 promise 是 eager 的,创建时就已经被(调度)执行了。
而 rust 这样的则是 lazy 的,你不 await 它就完全不会执行,这种情况下两者就一样了。
libook
2020-09-28 11:01:58 +08:00
简单理解的话:函数后面加括号就是调用函数的语法,第一种是在 await 后调用,第二种是先调用再用 await 接收结果。所以第一种是等前一个 timeoutPromise 执行完返回结果后再调用执行下一个函数;第二种是三个函数依次开始执行,执行的过程是同时进行的,在 await 部分是等待前一个执行完返回结果后才等待下一个执行完返回结果。

“存到变量”不是本质影响这个过程的因素,而是一种表象,本质是你的异步函数什么时候被调用的。可以去看看 Promise 的执行过程,await 一个 Promise 对象就是现在有结果就现在拿,现在没有结果就等着结果出来,结果出来拿到后再继续往下执行。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/710992

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX