详解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 相关文章推荐
关于javascript DOM事件模型的两件事
Jul 22 Javascript
网页右键ie不支持event.preventDefault和event.returnValue (需要加window)
Feb 22 Javascript
jquery动态加载js三种方法实例
Aug 03 Javascript
jQuery 获取和设置select下拉框的值实现代码
Nov 08 Javascript
JavaScript的arguments对象应用示例
Sep 15 Javascript
解决WordPress使用CDN后博文无法评论的错误
Dec 15 Javascript
JS实现拖动滚动条评分的效果代码分享
Sep 29 Javascript
Bootstrap Table使用心得总结
Nov 29 Javascript
JavaScript简单实现合并两个Json对象的方法示例
Oct 16 Javascript
Vant的安装和配合引入Vue.js项目里的方法步骤
Dec 05 Javascript
7个好用的JavaScript技巧分享(译)
May 07 Javascript
教你部署vue项目到docker
Apr 05 Vue.js
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+oracle 分页类
2006/10/09 PHP
PHP下MAIL的另一解决方案
2006/10/09 PHP
PHP中文URL编解码(urlencode()rawurlencode()
2010/07/03 PHP
解析PHP中$_FILES的使用以及注意事项
2013/07/05 PHP
使用PHP导出Word文档的原理和实例
2013/10/21 PHP
CI(CodeIgniter)框架中的增删改查操作
2014/06/10 PHP
JQuery获取浏览器窗口内容部分高度的代码
2012/02/24 Javascript
js获得页面的高度和宽度的方法
2014/02/23 Javascript
javascript监听鼠标滚轮事件浅析
2014/06/05 Javascript
js实现prototype扩展的方法(字符串,日期,数组扩展)
2016/01/14 Javascript
jQuery获取复选框被选中数量及判断选择值的方法详解
2016/05/25 Javascript
node.js路径处理方法以及绝对路径详解
2021/03/04 Javascript
完美解决JS文件页面加载时的阻塞问题
2016/12/18 Javascript
微信小程序 后台登录(非微信账号)实例详解
2017/03/31 Javascript
一篇看懂vuejs的状态管理神器 vuex状态管理模式
2017/04/20 Javascript
利用node.js写一个爬取知乎妹纸图的小爬虫
2017/05/03 Javascript
浅谈Angular4实现热加载开发旅程
2017/09/08 Javascript
使用express搭建一个简单的查询服务器的方法
2018/02/09 Javascript
JS简单获得节点元素的方法示例
2018/02/10 Javascript
浅谈Vue下使用百度地图的简易方法
2018/03/23 Javascript
基于React+Redux的SSR实现方法
2018/07/03 Javascript
使用iView Upload 组件实现手动上传图片的示例代码
2018/10/01 Javascript
微信小程序实现页面分享onShareAppMessage
2019/08/12 Javascript
vue.js购物车添加商品组件的方法
2019/09/17 Javascript
ant-design-vue中的select选择器,对输入值的进行筛选操作
2020/10/24 Javascript
Django框架登录加上验证码校验实现验证功能示例
2019/05/23 Python
用Python实现BP神经网络(附代码)
2019/07/10 Python
Django 对IP访问频率进行限制的例子
2019/08/30 Python
如何用Python 加密文件
2020/09/10 Python
研究生自荐信
2013/10/09 职场文书
中学生打架检讨书
2014/02/10 职场文书
小学兴趣小组活动总结
2014/07/07 职场文书
2014年安全生产工作总结
2014/11/13 职场文书
会计试用期工作总结2015
2015/05/28 职场文书
风之谷观后感
2015/06/11 职场文书
解析Redis Cluster原理
2021/06/21 Redis