详解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 Function对象扩展之延时执行函数
Jul 06 Javascript
js获取location.href的参数实例代码
Aug 02 Javascript
学习使用bootstrap基本控件(table、form、button)
Apr 12 Javascript
js select实现省市区联动选择
Apr 17 Javascript
js仿小米官网图片轮播特效
Sep 29 Javascript
jQuery Form表单取值的方法
Jan 11 Javascript
javascript 中设置window.location.href跳转无效问题解决办法
Feb 09 Javascript
Angular实现购物车计算示例代码
Feb 21 Javascript
原生js实现吸顶效果
Mar 13 Javascript
详解Vue开发微信H5微信分享签名失败问题解决方案
Aug 09 Javascript
浅谈关于JS下大批量异步任务按顺序执行解决方案一点思考
Jan 08 Javascript
vue中解决微信html5原生ios虚拟键返回不刷新问题
Oct 20 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 图片水印类代码
2012/08/27 PHP
Laravel框架基于ajax实现二级联动功能示例
2019/01/17 PHP
PHP保留两位小数的几种方法
2019/07/24 PHP
Jquery跨域获得Json时invalid label错误的解决办法
2011/01/11 Javascript
jquery 漂亮的删除确认和提交无刷新删除示例
2013/11/13 Javascript
jQuery中delegate与on的用法与区别示例介绍
2013/12/20 Javascript
jquery Ajax 实现加载数据前动画效果的示例代码
2014/02/07 Javascript
jQuery实现加入购物车飞入动画效果
2015/03/14 Javascript
Javascript类型系统之undefined和null浅析
2016/07/13 Javascript
利用JavaScript判断浏览器类型及版本
2016/08/23 Javascript
如何学JavaScript?前辈的经验之谈
2016/12/28 Javascript
angularJS深拷贝详解
2017/03/23 Javascript
详解angular2如何手动点击特定元素上的点击事件
2018/10/16 Javascript
vue-cli脚手架引入弹出层layer插件的几种方法
2019/06/24 Javascript
js实现一个简易计算器
2020/03/30 Javascript
微信小程序getLocation 需要在app.json中声明permission字段
2020/03/03 Javascript
javascript设计模式 ? 解释器模式原理与用法实例分析
2020/04/17 Javascript
微信小程序实现菜单左右联动
2020/05/19 Javascript
前端vue如何使用高德地图
2020/11/05 Javascript
新手该如何学python怎么学好python?
2008/10/07 Python
利用python批量给云主机配置安全组的方法教程
2017/06/21 Python
python如何使用正则表达式的前向、后向搜索及前向搜索否定模式详解
2017/11/08 Python
tensorflow训练中出现nan问题的解决
2018/02/10 Python
在cmd中运行.py文件: python的操作步骤
2018/05/12 Python
Python selenium根据class定位页面元素的方法
2019/02/26 Python
numpy.random.shuffle打乱顺序函数的实现
2019/09/10 Python
python 实现让字典的value 成为列表
2019/12/16 Python
Python安装与卸载流程详细步骤(图解)
2020/02/20 Python
Tensorflow使用Anaconda、pycharm安装记录
2020/07/29 Python
size?丹麦官网:英国伦敦的球鞋精品店
2019/04/15 全球购物
机电专业毕业生推荐信
2013/11/10 职场文书
学校后勤岗位职责
2014/02/19 职场文书
工地宣传标语
2014/06/18 职场文书
试用期转正工作总结2015
2015/05/28 职场文书
初中物理教学反思
2016/02/19 职场文书
如何使用Tkinter进行窗口的管理与设置
2021/06/30 Python