详解ES6中的三种异步解决方案
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
详解ES6中的三种异步解决⽅案
前置知识准备
1. Generator 函数执⾏会返回⼀个迭代器(Iterator), 在迭代器上可以调⽤ next() ⽅法, 执⾏下⼀个 yield 或 return
2. 调⽤ next() ⽅法,会返回⼀个对象 {value: res, done: false} , value 的值为 yield 之后表达式的值,done 的值表⽰迭代
器,是否已经执⾏完毕(最后⼀个yield 或 return )
3. next() ⽅法,可以传⼊⼀个值,做为前⼀个yield 表达式的返回值
有了这些知识,可以把Promise 对象做⼀个的 yield 的值,配合⼀个执⾏器,来处理异步操作
⽅式⼀: Generator + Promise + 执⾏器
const fs = require('fs')
// Promise 版的readFile
const readFile = function (fileName) {
return new Promise(function(resolve, reject) {
fs.readFile(fileName, function(err, data){
if (err) return reject(error);
resolve(data);
})
})
}
const gen = function * () {
let f1 = yield readFile('a.txt');
let f2 = yield readFile('b.txt');
console.log('F1--->', f1.toString());
console.log('F2--->', f2.toString());
}
// 基于 Generator 和 Promise 的⾃动执⾏器
function run(gen) {
let g = gen();
function next(data) {
let result = g.next(data);
if (result.done) return result.value;
result.value.then(function(data) {
next(data);
});
}
next();
}
run(gen);
执⾏器中的 result.value 现在是⼀个Promise, 通过 then ⽅法拿到需要的结果,传下⼀次 next ⽅法,这样 let f1 = yield readFile('a.txt'); 就可以拿到值!
⽅式⼆:Generator + Thunk函数 + 执⾏器
const fs = require('fs')
// 把⼀个单⼀执⾏的函数,变成需要再次调⽤的函数,固定⼀部分参数
function thunkify(fn, obj = {}) {
return function () {
let args = Array.from(arguments);
return function (m) {
args.push(m)
return fn.apply(obj, args)
}
}
}
const readFile = thunkify(fs.readFile, fs);
const gen = function* () {
let f1 = yield readFile('a.txt');
let f2 = yield readFile('b.txt');
console.log('F1-->', f1.toString());
console.log('F2-->', f2.toString());
}
// 基于 Generator 和 Thunk函数的⾃动执⾏器
function run(fn) {
let gen = fn();
function next(err, data) {
let result = gen.next(data);
if (result.done) return 1;
result.value(next);
}
next();
}
run(gen);
这⾥的 Thunk 转换器,把原来的 fs.readFile 函数转换成需要两次调⽤的函数,readFile 的执⾏结果,可以通过回调函数能参数传递出来,再传给 next ⽅法
⽅式三:基于 async 函数和 await 的异步处理⽅式
const fs = require('fs')
// Promise 版的readFile
const readFile = function (fileName) {
return new Promise(function(resolve, reject) {
fs.readFile(fileName, function(err, data){
if (err) return reject(err);
resolve(data);
})
})
}
const asyncReadFile = async function () {
const f1 = await readFile('a.txt');
const f2 = await readFile('b.txt');
console.log(f1.toString());
console.log(f2.toString());
};
asyncReadFile();
readFile 函数对⽐⽅式⼀没有⼤的变化,Generator 函数变成了 async 函数,可见这处⽅式只是⽅式⼀的⼀个语法
糖,async 函数⾃带了执⾏器!
这个话题,还可以衍⽣出 yield 的更多⽤法,下次再写,欢迎关注我!
以上就是本⽂的全部内容,希望对⼤家的学习有所帮助,也希望⼤家多多⽀持。