重学ES6(四) generator 与async函数

ES6新增了Generator与async函数

一、Generator的语法

形式上,Generator 函数是一个普通函数,但是有两个特征。一是,function关键字与函数名之间有一个星号;二是,函数体内部使用yield表达式,定义不同的内部状态。

function* Gen(){
    yield 1;
    yield 2;
    return 3;
}

var g = Gen();

Generator 函数与普通函数不同,Generator的返回值是一个遍历器对象,代表Generator状态的内部指针。使用()方式调用Generator函数,它不会执行。

使用Generator.next方法,来移动Generator状态的内部指针

function* Gen(){
  yield 1;
  yield 2;
  return 3;
}

var g = Gen();
console.log(g.next());  // {value:1 done: false}
console.log(g.next());  // {value:2 done: false}
console.log(g.next());  // {value:3 done: true}
console.log(g.next());  // {value:undefined done: true}
console.log(g.next());  // {value:undefined done: true}

Generator函数遇到 yield关键字会暂停执行,下一步,必须调用遍历器对象的next方法,使得指针移向下一个状态。也就是说,每次调用next方法,内部指针就从函数头部或上一次停下来的地方开始执行,直到遇到下一个yield表达式(或return语句)为止。换言之,Generator 函数是分段执行的,yield表达式是暂停执行的标记,而next方法可以恢复执行。

上面一共调用了六次next方法。

第一次、 指针指向 value 1 done 为false 表示遍历未结束

第二次、指针指向 value 2 done 为false 表示遍历未结束

第三次、指针指向 value 3 done 为true 表示遍历已结束

第四次、指针指向 value undefined done 为true 表示遍历已结束

return以后每次调用next value都为undefined

二、Generator的异步应用

由于Generator分段执行的特点,它可以用来处理异步操作。

const fs = require('fs');

const readFile = function (fileName) {
  return new Promise(function (resolve, reject) {
    fs.readFile(fileName, function(error, data) {
      if (error) return reject(error);
      resolve(data);
    });
  });
};

const gen = function* () {
  const f1 = yield readFile('/etc/fstab');
  const f2 = yield readFile('/etc/shells');
  console.log(f1.toString());
  console.log(f2.toString());
};

三、 async函数

async函数是generator的语法糖。简单的说async就相当于*,await相当于yield。

上面的gen函数可以这样改写:

const asyncReadFile = async function () {
  const f1 = await readFile('/etc/fstab');
  const f2 = await readFile('/etc/shells');
  console.log(f1.toString());
  console.log(f2.toString());
};

当然async与Generator并不完全一样,主要有以下区别:

1.内置执行器 不再需要调用.next执行, async的执行与普通函数一样。

2.async返回的是一个promise对象。可以调用.then来执行下一步操作,async函数的返回值会被then回调方法接收到

async函数在执行时,一旦遇到await就先返回,直到异步操作完成,再执行函数体后面的语句。

上代码:

var timeout = (delay) => {
	return new Promise((resolve,reject)=>{
		setTimeout(()=>{
			resolve();
		},delay)
	})
}

async function delayPrint (value,delay){
	await timeout(delay)
	console.log(value)
}

delayPrint('2秒后输出',2000)

const testPromise = async() =>{
	return 'async会返回一个promise对象!';
}

testPromise().then((data)=>{
	console.log(data)
})

 

你可能感兴趣的:(javascript)