继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

ES6 中的 三种异步解决方案

泛舟湖上清波郎朗
关注TA
已关注
手记 270
粉丝 32
获赞 226
部分案例来自 阮一峰 的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 的更多用法 ,下次再写,欢迎关注我!


作者:小西在深圳
链接:https://juejin.im/post/5b30c555e51d4558dd699395
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
打开App,阅读手记
1人推荐
发表评论
随时随地看视频慕课网APP