js异步编程三、生成器函数、Gennerator、Async/Await语法糖
程序员文章站
2022-04-30 09:10:04
...
生成器函数就是在普通函数上多了上*号,当调用这个生成器函数的时候不会立即执行函数,而且得到一个生成器对象,直接手动的调用这个生成器的next方法,这个函数的函数体才会开始执行。
在函数的内容可以使用yield的关键词向外返回一个值,在next方法调用的时候可以拿到这个值,在返回的对象中还有个done属性,用来表示这个生成器是否已经全部执行完,而且yield关键词并不会像return一样立即结束函数,只是暂停这个生成器函数,直到下一次调用next方法会继续从yield位置向下执行。
如果给next传参数,会做成yield语句的返回值.
function* foo() {
console.log("start");
const res = yield "foo";
console.log(res);
}
const generator = foo();
const result = generator.next();
console.log(result);
如果说在外部调用的是生成器throw方法,那这个方法就可以对生成器函数内部抛出一个异常.
function* foo() {
console.log("start");
try {
const res = yield "foo";
console.log(res);
} catch (e) {
console.log(e);
}
}
const generator = foo();
const result = generator.next();
console.log(result);
generator.throw(new Error("Generator error"));
Gennerator异步方案(生成器函数):
function ajax(url) {...}
function* main() {
const user = yield ajax(user.json);
console.log(users);
}
const g = main();
const result = g.next();
result.value.then(data => {
g.next(data);
});
用这种方法彻底的消灭了promise的回调,有了近乎于同步代码的体验。多个接口时可以在main中做多个yield的操作。在外部第二次调用的结果也是一个promise对象,一样的接收到value再调用里面的then方法。
function ajax(url) {...}
function* main() {
const user = yield ajax(user.json);
console.log(users);
const posts = yield ajax(posts.json);
console.log(posts);
}
const g = main();
const result = g.next();
result.value.then(data => {
const result2 = g.next(data);
result2.value.then(data => {
g.next(data);
});
});
直到返回的done属性为true,说明main方法里执行完,可以用递归的方式,直接done为true结束函数.可以把这个封装成公共的函数。
function ajax(url) {...}
function* main() {
const user = yield ajax(user.json);
console.log(users);
const posts = yield ajax(posts.json);
console.log(posts);
}
function co(gennerator) {
const g = generator();
function handleResult(result) {
if (result.done) return; //生成器函数结束
result.value.then(
data => {
handleResult(g.next(data));
},
error => {
g.throw(error);
}
);
}
handleResult(g.next());
}
co(main);
像这样的生成器函数执行器在社区中就有一个更完善的co库
也可以直接使用Async/Await语法糖(语言层面的异步编程标准)
async function main() {
try {
const user = await ajax(user.json);
console.log(users);
const posts = await ajax(posts.json);
console.log(posts);
} catch (e) {
console.log(e);
}
}
async最大的好处是不需要配合类似于co这样的执行器,因为这是标准语言层面的异步编程语法,其次async函数会返回一个promise对象,更加利于对整体代码的控制。注意await关键词只能出现在async内部