Generator yield语法和 co模块

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);
}

  

原文地址:https://www.cnblogs.com/muamaker/p/8806462.html