详解ES6中的三种异步解决方案


Posted in Javascript onJune 28, 2018

前置知识准备

  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 的更多用法 ,下次再写,欢迎关注我!

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
DB.ASP 用Javascript写ASP很灵活很好用很easy
Jul 31 Javascript
javascript限制文本框只允许输入数字(曾经与现在的方法对比)
Jan 18 Javascript
使用js实现关闭js弹出层的窗口
Feb 10 Javascript
AngularJS语法详解(续)
Jan 23 Javascript
javascript 应用小技巧方法汇总
Jul 05 Javascript
JS基于Mootools实现的个性菜单效果代码
Oct 21 Javascript
3种js实现string的substring方法
Nov 09 Javascript
基于jquery实现的银行卡号每隔4位自动插入空格的实现代码
Nov 22 Javascript
基于JavaScript实现Tab选项卡切换效果
Nov 24 Javascript
AngularJS实现自定义指令及指令配置项的方法
Nov 20 Javascript
JS实现字符串去重及数组去重的方法示例
Apr 21 Javascript
layui中table表头样式修改方法
Aug 15 Javascript
Auto.js自动收取自己和好友蚂蚁森林能量脚本
Jun 28 #Javascript
使用vue-router完成简单导航功能【推荐】
Jun 28 #Javascript
vue如何引入sass全局变量
Jun 28 #Javascript
小程序实现带年月选取效果的日历
Jun 27 #Javascript
浅谈Angular6的服务和依赖注入
Jun 27 #Javascript
JS实现获取进今年第几天是周几的方法分析
Jun 27 #Javascript
vue+springmvc导出excel数据的实现代码
Jun 27 #Javascript
You might like
通过具体程序来理解PHP里面的抽象类
2010/01/28 PHP
Wordpress 相册插件 NextGEN-Gallery 添加目录将中文转为拼音的解决办法
2010/12/29 PHP
YII2框架中excel表格导出的方法详解
2017/07/21 PHP
一段利用WSH修改和查看IP配置的代码
2008/05/11 Javascript
jquery.alert 弹出式复选框实现代码
2009/06/15 Javascript
原生js实现移动端瀑布流式代码示例
2015/12/18 Javascript
jQuery插件开发精品教程让你的jQuery提升一个台阶
2016/01/27 Javascript
jQuery插件ImageDrawer.js实现动态绘制图片动画(附源码下载)
2016/02/25 Javascript
如何通过js实现图片预览功能【附实例代码】
2016/03/30 Javascript
js实现按钮控制带有停顿效果的图片滚动
2016/08/30 Javascript
走进AngularJs之过滤器(filter)详解
2017/02/17 Javascript
移动端利用H5实现压缩图片上传功能
2017/03/29 Javascript
微信小程序新增的拖动组件movable-view使用教程
2017/05/20 Javascript
Vue ElementUi同时校验多个表单(巧用new promise)
2018/06/06 Javascript
vue+iview/elementUi实现城市多选
2019/03/28 Javascript
Vue项目使用localStorage+Vuex保存用户登录信息
2019/05/27 Javascript
ES6之Proxy的get方法详解
2019/10/11 Javascript
Vue 数组和对象更新,但是页面没有刷新的解决方式
2019/11/09 Javascript
微信小程序视频弹幕发送功能的实现
2020/12/28 Javascript
[05:46]DOTA2英雄梦之声_第18期_陈
2014/06/20 DOTA
[00:52]黑暗之门更新 新英雄孽主驾临DOTA2
2016/08/24 DOTA
Python2.x版本中基本的中文编码问题解决
2015/10/12 Python
python flask实现分页效果
2017/06/27 Python
Python中Scrapy爬虫图片处理详解
2017/11/29 Python
Python+OpenCV实现图像融合的原理及代码
2018/12/03 Python
pyinstaller打包多个py文件和去除cmd黑框的方法
2019/06/21 Python
django用户登录验证的完整示例代码
2019/07/21 Python
tensorflow保持每次训练结果一致的简单实现
2020/02/17 Python
python实现猜数游戏(保存游戏记录)
2020/06/22 Python
css3使网页、图片变成灰色兼容大多数浏览器
2014/07/02 HTML / CSS
Set里的元素是不能重复的,那么用什么方法来区分重复与否呢? 是用==还是equals()? 它们有何区别?用contains来区分是否有重复的对象。还是都不用
2013/07/30 面试题
校车安全管理责任书
2015/05/11 职场文书
催款律师函范文
2015/05/27 职场文书
小学思想品德教学反思
2016/02/24 职场文书
2016年中学植树节活动总结
2016/03/16 职场文书
2016年“我们的节日·端午节”活动总结
2016/04/01 职场文书