Generator yield 语法使用,也叫生成器,实际上就是多个异步按顺序执行
function* gen(){
//第一步 开始
console.log("start");
var a = yield "aaa"; //第二步
console.log("---",a); //2
var x = yield 222; //第三步
console.log("---",x);//3
var y = yield 4; //第四步
console.log("---",y);//6 return "over"
}
var g = gen(); //任何东西都没有执行,返回的一个迭代器, 可以使用 for of 遍历 // next 的传值是上一段 yield 的返回值 console.log(g.next(1));
console.log(g.next(2));
console.log(g.next(3));
console.log(g.next(6));
可以看到,上面最后的调用,是可以封装成递归的,免得重复代码,多层嵌套,比如自己写一个,自运行的
const promisify = require("util").promisify;
const fs = require("fs");
const readFile = promisify(fs.readFile);
const path = require("path");
function resolve(p){
return path.resolve(__dirname,p);
} function* gen(){
var data1 = yield readFile(resolve("./data/data1.json"),"utf-8");
console.log(data1);
var data2 = yield readFile(resolve("./data/data2.json"),"utf-8");
console.log(data2); var num = yield 123456; console.log(num);
} //简单版自运行co模块
function co(gen){
var g = gen(); //任何东西都没有执行,返回的一个迭代器
function next(res){
var result = g.next(res);
if(!result.done){
Promise.resolve(result.value).then((res)=>{
next(res);
}).catch((e)=>{
throw new Error(e);
})
}
}
next();
} co(gen);
或者使用co模块
const fs = require('fs');
const co =require('co');
const readFile = function (fileName) {
return new Promise(function (resolve, reject) {
fs.readFile(fileName, "utf-8",function(error, data) {
if (error) return reject(error);
resolve(data);
});
});
}; const gen = function* () {
const f1 = yield readFile('./data1.txt');
const f2 = yield readFile('./data2.txt');
console.log(f1);
console.log(f2);
}; co(gen).then(function(data){ console.log(data); }).catch(function(ct){ console.log(ct); })
Yield * 表达式
如果在 Generator 函数内部,调用另一个 Generator 函数。需要在前者的函数体内部,自己手动完成遍历。
function* foo() {
yield 'a';
yield 'b';
} function* bar() {
yield 'x';
// 手动遍历 foo()
for (let i of foo()) {
console.log(i);
}
yield 'y';
} for (let v of bar()){
console.log(v);
}
ES6 提供了yield*
表达式,作为解决办法,用来在一个 Generator 函数里面执行另一个 Generator 函数。
function* bar() {
yield 'x';
yield* foo();
yield 'y';
}
flat 数组
var arr = [1, [[2, 3], 4], [5, 6]]; var flat = function* (a) {
a.forEach(function (item) {
if (typeof item !== 'number') {
yield* flat(item);
} else {
yield item;
}
});
}; for (var f of flat(arr)){
console.log(f);
}