进入之前,首先我们要先知道一下为什么有asnyc/await?
在没有这两个语法糖之前,我们实现调用封装promise 通常是 xx().then().then().catch() 虽然这是避免了之前的地狱回调,但是在内部异步任务较多的情况下,不断去.then(),也会带来难以追踪,不好维护问题。
我们再看这两个语法糖的用法
async:被标记的函数 始终返回的是一个promise;
await: 使用于async内部,标记在promise前面(module顶层也可以)
代码示例
function fetchData() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve("Data fetched successfully!");
}, 1000);
});
}
async function main() {
try { // 可以通过try-catch捕捉异常
const data = await fetchData();
console.log(data);
} catch (error) {
console.error(error);
}
}
思考一下原理实现
async 内部返回了promise,await在**等待?**promise
引入生成器概念
语法
/* 语法 yied关键字暂停 */
function * bar(){
console.log('step 1')
yield 1
console.log('step 2')
yield 2
console.log('step 3')
yield 3
// 注意 如果为return 此时状态为done,for...of 循环不会捕捉到return的值,所以需要手动处理 next()
return 4
}
是不是跟await类似?
我们可以把这个生成器作为async内部处理的代码来模拟一下
function asyncGenerator(func) {
return function (...args) {
const gen = func(...args);
function handleNext(result) { // 处理生成器iterable,这里是不是返回了一个promise?
if (result.done) {
return Promise.resolve(result.value);
}
return Promise.resolve(result.value).then(res=>{
return handleNext(gen.next(res));
}).catch(err=>{
return handleNext(gen.throw(err));
});
}
return handleNext(gen.next());// 简写,正常这里需要捕捉异常
}
}
yied关键字暂停
const mockAsyncFunc = asyncGenerator(function* () {
try {
const result1 = yield Promise.resolve(1);
console.log(result1);
const result2 = yield Promise.resolve(2);
console.log(result2);
const result3 = yield Promise.resolve(3);
console.log(result3);
return 4;
} catch (err) {
console.log(err);
}
});
//正常调用实现
mockAsyncFunc().then(res => { console.log(res); })
努力学习中ing,本文若有不足之处,还望大家指出~