async 和 await 关键字让我们可以用一种更简洁的方式写出基于 Promise 的异步行为,而无需刻意地链式调用 promise。
场景
Promise B需要接受 Promise A的返回值作为下一步计算的参数
1 2 3 4 5 6 7 8 9 10 11
| function promiseA() { return new Promise((resolve, reject) => { resolve(1); }) }
function promiseB(value) { return new Promise((resolve, reject) => { resolve(`value: ${value}`) }) }
|
在没有async/await时,需要嵌套调用`Promise.then()`
1 2 3 4 5
| promiseA().then(res => { promiseB(res).then(res2 => { console.log(res2) }) })
|
使用`async/await`:
1 2 3 4 5 6 7
| const fun = async () => { const res = await promiseA(); const res2 = await promiseB(res); console.log(res2) }
fun()
|
对比起来,async/await 更像是在同步处理异步问题,更符合人的阅读直觉。
函数生成器模拟实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
| function promise1() { return new Promise((resolve) => { setTimeout(() => { resolve("1"); }, 1000); }); }
function promise2(value) { return new Promise((resolve, reject) => { setTimeout(() => { resolve("value:" + value); }, 1000); }); }
function promise3(value) { return new Promise((resolve, reject) => { setTimeout(() => { resolve("value:" + value); }, 1000); }); }
function* readFile() { const value = yield promise1(); const value2 = yield promise2(value); const result = yield promise3(value2); return result; }
function asyncGen(fn) { const g = fn(); return new Promise((resolve, reject) => { function next(param) { const { value, done } = g.next(param); if (!done) { Promise.resolve(value).then( (res) => { next(res); }, (err) => { reject(err); } ); } else { resolve(param); } }
next(); }); }
asyncGen(readFile).then( (res) => console.log(res), (err) => console.log(err) );
|