异步编程
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后面返回的就是上一个)异步操作的完成
- 没有显式return,相当于return Promise.resolve(undefined);
- return非Promise的数据data,相当于return Promise.resolve(data);
- 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 模块
应用场景
- 动态依赖导入
const strings = await import(/i18n/${navigator.language}); - 资源初始化
const connection = await dbConnector();(可以在模块不能使用时抛出错误。) - 依赖回退
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 作为备份加载。)