为什么将 promise 存到变量中,这三个 promise 就会同时运行,而不是阻塞后面代码的运行
1
abelmakihara 2020-09-27 17:09:20 +08:00
因为是 await 阻塞在那的
第二个例子是执行完了再一起拿结果的 |
2
noe132 2020-09-27 17:15:21 +08:00 1
因为第一个例子等同于
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') |
3
Curtion 2020-09-27 17:19:09 +08:00
上面的例子中第一个 timeoutPromise 在 resolve 后才会继续注册第二个 timeoutPromise 微任务;而第二个例子在当前 Event Loop 中就一次性注册了三个微任务。
|
4
wxsm 2020-09-27 17:21:18 +08:00
#2 说得很好了。
|
5
siwadiya OP @abelmakihara 可以这么理解吗: 这三个 promise 是同步运行的,后面的 await 是为了将 pending 更改为 fulfilled
|
6
abelmakihara 2020-09-27 17:26:35 +08:00 1
@siwadiya 当然不是了 是 await 在等待着状态变更的返回结果 因果反了
他们都是'同步'运行了 3s 所以 await 拿结果的时候非常快 不然像#2 的那样 await timeoutPromise2/3 的时候还是需要再各等待 1s 的 |
7
Reapper 2020-09-27 17:33:20 +08:00
#2 已经很详细了,第一个例子中是 3s 3s 3s,第二个例子中,先执行了 3 个 promise,然后开始等待,3s 后有结果了,然后输出 输出 输出,async/await 只是一个语法糖,建议理解一下 promise 的执行过程
|
8
yzqtdu 2020-09-27 17:59:22 +08:00
个人观点,这里不存在所谓的阻塞,generator 在 yield 之后阻塞了后续命令的执行吗?没有,执行流只是切换到其他栈去了,在合适的时机可以跳回 yield 之后的命令。async/await promise 这些都不阻塞执行流,要说阻塞,同步阻塞 io 或者 sleep 才是真的阻塞吧
|
9
SoloCompany 2020-09-27 19:18:26 +08:00 via iPhone
如果希望去掉无意义的返回值
可以用 await Promise.all |
10
Jirajine 2020-09-27 19:25:04 +08:00 via Android
因为 js 的 promise 是 eager 的,创建时就已经被(调度)执行了。
而 rust 这样的则是 lazy 的,你不 await 它就完全不会执行,这种情况下两者就一样了。 |
11
libook 2020-09-28 11:01:58 +08:00
简单理解的话:函数后面加括号就是调用函数的语法,第一种是在 await 后调用,第二种是先调用再用 await 接收结果。所以第一种是等前一个 timeoutPromise 执行完返回结果后再调用执行下一个函数;第二种是三个函数依次开始执行,执行的过程是同时进行的,在 await 部分是等待前一个执行完返回结果后才等待下一个执行完返回结果。
“存到变量”不是本质影响这个过程的因素,而是一种表象,本质是你的异步函数什么时候被调用的。可以去看看 Promise 的执行过程,await 一个 Promise 对象就是现在有结果就现在拿,现在没有结果就等着结果出来,结果出来拿到后再继续往下执行。 |