ES6新增了Generator与async函数
形式上,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分段执行的特点,它可以用来处理异步操作。
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函数是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)
})