参考promise详解:https://juejin.cn/post/6844903664209887246
async、await
使用 async/await, 搭配promise,可以通过编写形似同步的代码来处理异步流程, 提高代码的简洁性和可读性
async 用于申明一个 function 是异步的,而 await 用于等待一个异步方法执行完成
当一个函数被async修饰以后, 它的返回值会被自动处理成Promise对象
await不仅等待Promise完成, 而且还拿到了resolve方法的参数
1、async
async用来表示函数是异步的,定义的async函数返回值是一个promise对象,可以使用then方法添加回调函数。
async function func1() { return 123; } func1().then(val => { console.log(val); // 123 }); <!-- 若 async 定义的函数有返回值,return 123; 相当于Promise.resolve(123),没有声明式的 return则相当于执行了Promise.resolve(); -->
2、await, await 后面的代码都得等着。
await 可以理解为是 async wait 的简写。await 必须出现在 async 函数内部,不能单独使用。 函数中只要使用await,则当前函数必须使用async修饰
await后面可以跟任何的JS表达式,
function notAsyncFunc() { await Math.random(); } notAsyncFunc(); <!-- Uncaught SyntaxError: Unexpected identifier Uncaught SyntaxError: await仅在异步函数中有效 -->
// 下面这种通过async修饰的就不会报错
async function test() {
await Math.random();
}
test();
一个真实的例子:
实现串行的异步,上一个异步请求的返回结果是下一个请求的参数
//我们仍然使用 setTimeout 来模拟异步请求 function sleep(second, param) { return new Promise((resolve, reject) => { setTimeout(() => { resolve(param); }, second); }) } async function test() { let result1 = await sleep(2000, 'req01'); // 这个await 会阻塞后面的代码执行。 console.log(` ${result1}`); let result2 = await sleep(1000, 'req02' + result1); console.log(` ${result2}`); let result3 = await sleep(500, 'req03' + result2); console.log(` ${result3}`); } test(); VM913:14 // 间隔定时器的时间分别打印出下面的值 req01 req02req01 req03req02req01 -->
使用for循环+ async/await
function sleep(second, param) { return new Promise((resolve, reject) => { setTimeout(() => { resolve({req: param}); }, second); }); } const list = ['req01', 'req02', 'req03']; const test = async (list) => { let obj = {}; for (let i = 0; i < list.length; i++) { obj = await sleep(2000, list[i]); console.log(obj); } }; // 随着定时器的间隔,依次输出 { req: 'req01' } { req: 'req02' } { req: 'req03' }
使用reduce来实现串行的请求
下面的代码和第一次的代码实现的是一样的
reduce函数整体是个同步函数,自己先执行完毕构造Promise队列,然后在内存异步执行,
而利用 async/await 的函数是利用将自己改造为一个异步函数,等待每一个 Promise 执行完毕。
function sleep(second, param,obj1) { return new Promise((resolve, reject) => { setTimeout(() => { resolve({req: param + obj1}); }, second); }); } const list = ['req01', 'req02', 'req03']; const test = async (list) => { list.reduce(async (memo, ele) => { const {req = ''} = await memo; const obj = await sleep(2000, ele, req); console.log(obj); return obj; },Promise.resolve( {} )); // 输出 { req: 'req01' } { req: 'req02req01' } { req: 'req03req02req01' }
ES7中新增的“语法糖”:async await
- 函数中只要使用await,则当前函数必须使用async修饰
- async是把修饰一个函数,控制其返回的结果是一个Promise实例
- await可以理解为把一个异步操作修饰为同步的效果(但是它还是异步)