async await底层原理
async/await是基于Promise和Generator实现的语法糖,底层通过生成器函数和状态机将异步转为同步写法。核心是一个自动执行器(spawn函数),它管理生成器状态,处理Promise解析:当await表达式返回Promise时,执行器暂停生成器;Promise解决后恢复执行,成功时传递结果值,失败时抛出错误。这种机制使得异步代码能以同步方式书写,同时保持非阻塞特性。(150字)
async await 语法是ES7
出现的,是基于ES6的 promise和generator实现的,那么js底层是如何实现的呢,让promise异步状态变为await的同步写法。
async/await 是建立在Promise之上的语法糖,它的底层实现原理是基于状态机的转换和生成器(Generator)函数。下面我将详细描述其工作原理。
-
生成器函数(Generator)和迭代器(Iterator)
生成器函数可以暂停和恢复执行。当调用生成器函数时,它返回一个迭代器对象,通过调用迭代器的next()方法可以逐步执行生成器函数体。每次遇到yield关键字,函数就会暂停执行并返回一个值。 -
将异步操作转化为同步写法
async/await 通过暂停和恢复执行来实现异步操作的同步写法。async函数本质上是一个生成器函数,但使用了async关键字标记。await后面的表达式会被包装成Promise。 -
状态机的实现
编译器(如Babel)会将async函数转换成生成器函数的形式,然后使用一个状态机(通常由一个包装函数实现)来管理生成器的状态,自动执行迭代过程。
转换步骤:
假设有这样一个async函数:
async function example() {
const result = await someAsyncCall();
console.log(result);
}
它会被转换成类似下面的生成器函数:
function example() {
return spawn(function* () {
const result = yield someAsyncCall();
console.log(result);
});
}
这里的spawn函数就是一个自动执行器,它会管理生成器的状态,处理Promise的解析,并继续执行生成器直到结束。
- 自动执行器(spawn函数)的实现
自动执行器的作用是管理生成器的状态,处理每个yield出来的Promise,并根据Promise的结果(成功或失败)决定是继续执行还是抛出错误。
一个简化的自动执行器可能如下:
function spawn(generatorFunc) {
return new Promise((resolve, reject) => {
const generator = generatorFunc();
const step = (key, arg) => {
let result;
try {
result = generator[key](arg);
} catch (error) {
return reject(error);
}
const { value, done } = result;
if (done) {
return resolve(value);
}
// 确保返回一个Promise
Promise.resolve(value).then(
value => step('next', value),
error => step('throw', error)
);
};
step('next');
});
}
步骤解析:
spawn函数返回一个Promise,这样调用者可以使用.then()和.catch()。
创建生成器对象generator。
定义一个step函数,用于控制生成器的执行。它根据状态(‘next’或’throw’)调用生成器的相应方法(generator.next()或generator.throw())。
在首次调用时,使用step(‘next’)启动生成器。
每次执行生成器的next或throw方法,都会返回一个对象{ value, done },其中value是yield后面的表达式的值(通常是一个Promise),done表示生成器是否已经结束。
如果生成器未结束(done为false),则等待Promise解析(使用Promise.resolve来确保它是一个Promise),然后根据解析结果:
- 若成功,则使用step(‘next’, value)将解析后的值传给生成器,并继续下一步。
- 若失败,则使用step(‘throw’, error)将错误抛出到生成器内部,可以被生成器内的try-catch捕获。
如果生成器结束(done为true),则解析外部的Promise(即整个async函数的Promise)为生成器函数返回的值(即return的值)。
- 错误处理
在async函数中,错误通过try-catch捕获。在自动执行器中,当生成器内部出现错误(包括异步操作reject)时,我们使用generator.throw()将错误抛入生成器,这样生成器内部如果有try-catch,就能捕获错误。
更多推荐
所有评论(0)