- 作者:老汪软件技巧
- 发表时间:2024-11-14 21:01
- 浏览量:
Async和Await是ES7中提出对异步操作的解决方案,也有说Async和Await是Generator的语法糖
// 模拟异步操作;
function sayHi(name) {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log('hi', name);
resolve()
})
})
}
async function getPeople() {
await sayHi('Bob');
await sayHi('Flank')
}
ES6 - Generator
Generator是ES6提出的一种异步编程的解决方案, 如果用Generator来实现异步操作
如果对Generator语法不清楚的可以了解阮一峰 ECMAScript 6 (ES6) 标准入门教程 第三版,主要就是函数形态上有*,通过yield来定义不同的状态,并且返回一个迭代器对象;
function sayHi(name) {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log('hi', name);
resolve()
})
})
}
function* getPeople() {
yield sayHi('Bob');
yield sayHi('Flank');
return 'ending';
}
var hw = getPeople();
// 返回一个迭代器对象
hw.next()
// { value: Promise, done: false }
hw.next()
// { value: Promise, done: false }
hw.next()
// { value: 'ending', done: true }
hw.next()
// { value: undefined, done: true }
ES5 - regeneratorRuntime
如果需要考虑到浏览器的兼容性,对ES6语法的兼容,我们也可以采用babel转译该语法向下兼容转换成ES5的语法
转换后语法
function sayHi(name) {
return new Promise(function (resolve, reject) {
setTimeout(function () {
console.log('hi', name);
resolve();
});
});
}
function getPeople() {
return regeneratorRuntime.async(function getPeople$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
_context.next = 2;
return regeneratorRuntime.awrap(sayHi('Bob'));
case 2:
_context.next = 4;
return regeneratorRuntime.awrap(sayHi('Flank'));
case 4:
case "end":
return _context.stop();
}
}
}, null, null, null, Promise);
}
可以看到其中的关键的函数regeneratorRuntime, regeneratorRuntime 是facebook regenerator库提供的API,主要用来将基于 ES6 generator 和 async/await 的代码转换成 ES5 兼容的代码;
regeneratorRuntime原理, regeneratorRuntime中async函数的原理,是上下文保存,每次执行yield的时候,都执行一遍包装的函数,用context来维护上下文;
下面实现一个简单的regeneratorRuntime
// 全局维护context对象来存储函数执行的上下文;
const Context = {
next: 0,
prev: 0,
done: false,
stop: () => {
this.done = true;
}
}
// gen函数用来封装yield的不同函数的执行
function gen(context) {
while (1) {
switch (context.prev = context.next) {
case 0:
debugger
context.next = 2;
return sayHi('Bob');
case 2:
context.next = 4;
return sayHi('Flank');
case 4:
context.stop();
return undefined
}
}
}
// 定义next(),进行迭代器的一个执行;
let getPeople = function () {
return {
next: function () {
value = gen$Context);
done = Context.done
return {
value,
done
}
}
}
}