异步编程

2021-09-27 43

异步编程

概念

async 解决的问题和定义
Promise 的定义
Promise 的 三种状态
帮助理解new Promise(function (resolve, reject){}
Promise.then() 的定义
Promise和async/await 的关系

用法

async 一个实例

function fn(){
  return new Promise(resolve=>{
  console.log(1)
  resolve()
 })
}
async function f1(){
 await fn()
  console.log(2)
}
f1()
console.log(3)
//1
//3
//2

解释 : 因为await是从右向左的执行顺序,先执行fn(),打印1,然后遇到await,阻塞后面的console.log(2),先退出fn执行同步代码console.log(3),然后发现没有同步代码了,返回await,执行后续的console.log(2),所以结果为1 3 2

async函数的返回值总是一个Promise

无论async函数有无await操作,其总是返回一个Promise,可以用then方法指定下一步的操作。每一个 Promise 都是有某一个(跟在你then后面返回的就是上一个)异步操作的完成

  1. 没有显式return,相当于return Promise.resolve(undefined);
  2. return非Promise的数据data,相当于return Promise.resolve(data);
  3. return Promise, 会得到Promise对象本身

接受返回值

  • .then 然后输出:data.then( num => { console.log(num) } )
  • await :const data = await main();  console.log(data)

确保所有异步请求都完成

官方文档
阮一峰的笔记)

async + await 和 同步执行区别:

  • async函数内阻塞
  • 函数外不阻塞

async + await 和Promise执行, 更美观

假设一个业务,分多个步骤完成,每个步骤都是异步的,而且依赖于上一个步骤的结果。

  • Promise 方式,写成

function takeLongTime(n) {
    return new Promise(resolve => {
  setTimeout(() => resolve(n + 200), n);
 });
}

function step1(n) {
    console.log(step1 with ${n});
 return takeLongTime(n);
}

function step2(n) {
    console.log(step2 with ${n});
 return takeLongTime(n);
}

function doIt() {
  const time1 = 300;
  step1(time1)
 .then(time2 => step2(time2))
  .then(time3 => step3(time3))
   .then(result => {
    console.log(result is ${result});
    console.timeEnd("doIt");
  });
}

  • async/await 写成:

async function doIt() {
 console.time("doIt");
 const time1 = 300;
 const time2 = await step1(time1);
 const time3 = await step2(time2);
 const result = await step3(time3);
 console.log(·result is ${result});
 console.timeEnd("doIt");
}

参考链接: async/await 的优势在于处理 then 链

顶层 await

  • Node V8:
  • TS 3.8
  • ES 模块

应用场景

  1. 动态依赖导入
    const strings = await import(/i18n/${navigator.language});
  2. 资源初始化
    const connection = await dbConnector();(可以在模块不能使用时抛出错误。)
  3. 依赖回退

let jQuery;
try {
jQuery = await import('https://cdn-a.example.com/jQuery');
} catch {
jQuery = await import('https://cdn-b.example.com/jQuery');
}

(会从 CDN A 加载 JavaScript 库,如果它加载失败会将 CDN B 作为备份加载。)