Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

关于async和await的“同步” #11

Open
metroluffy opened this issue Apr 27, 2020 · 1 comment
Open

关于async和await的“同步” #11

metroluffy opened this issue Apr 27, 2020 · 1 comment
Assignees

Comments

@metroluffy
Copy link
Owner

metroluffy commented Apr 27, 2020

关于async和await的“同步”

题目

要求看代码写输出。

function wait(){
  return new Promise(resolve =>
    setTimeout(resolve, 10*1000)
  )
}
async function func1() {
  console.time('time-func1')
  const x = await wait()
  const y = await wait()
  const z = await wait()
  console.timeEnd('time-func1')
}
async function func2() {
  console.time('time-func2')
  const x = wait()
  const y = wait()
  const z = wait()
  await x
  await y
  await z
  console.timeEnd('time-func2')
}
func1()
func2()

/** 输出如下
 * time-func2:10002.4ms
 * time-func1: 32261.5ms
 */

解析

async、await语法糖让我们可以把Promise的异步回调处理写出“同步”的方式,即代码看起来是同步并且整洁很多,但其目的是简化使用多个 promise 时的同步行为,并非是真同步。

await 表达式会暂停当前 async function 的执行,等待 Promise 处理完成。若 Promise 正常处理(fulfilled),其回调的resolve函数参数作为 await 表达式的值,继续执行 async function。

如此相邻的两个 await wait() 会形成继发关系(串行)。要写成并发方式,可以如 func2函数所示用变量先缓存Promise,再一起执行,或者你也可以使用 Promise.all / Promise.allSettled,没有依赖关系的函数最好让它们同时触发。

注意:Promise.all 有短路效应,如果参数中 promise 有一个失败(rejected),此实例回调失败(reject),失败的原因是第一个失败 promise 的结果。

async function func3() {
  console.time('time-func3')
  await Promise.all([wait(),wait(),wait()])
  console.timeEnd('time-func3')
}
func3()
// time-func3: 10455.867919921875ms

更多请参见: MDN-async function

@metroluffy
Copy link
Owner Author

metroluffy commented Mar 5, 2021

这里的解析存在问题,真实情况应该是Promise constructor同步执行,await则会暂停当前async执行直到结果返回,相对而言,串行变成了并发。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant