详解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中的图片添加到第二个div中示例
Oct 08 Javascript
浅谈Javascript Base64 加密解密
Dec 28 Javascript
微信小程序 视图容器组件的详解及实例代码
Jan 19 Javascript
canvas绘图不清晰的解决方案
Feb 28 Javascript
jquery仿ps颜色拾取功能
Mar 08 Javascript
node.js+captchapng+jsonwebtoken实现登录验证示例
Aug 17 Javascript
Vue-cli-webpack搭建斗鱼直播步骤详解
Nov 17 Javascript
JavaScript 下载svg图片为png格式
Jun 21 Javascript
React styled-components设置组件属性的方法
Aug 07 Javascript
vue中 this.$set的用法详解
Sep 06 Javascript
JS this关键字在ajax中使用出现问题解决方案
Jul 17 Javascript
如何利用javascript接收json信息并进行处理
Aug 06 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
PHP6 mysql连接方式说明
2009/02/09 PHP
比较discuz和ecshop的截取字符串函数php版
2012/09/03 PHP
关于PHP结束标签的使用细节探讨及联想
2013/03/04 PHP
php调用shell的方法
2014/11/05 PHP
PHP中使用数组指针函数操作数组示例
2014/11/19 PHP
浅谈PHP进程管理
2019/03/08 PHP
获取数组中最大最小值方法js代码(自写)
2013/08/12 Javascript
js根据鼠标移动速度背景图片自动旋转的方法
2015/02/28 Javascript
javascript获取本机操作系统类型的方法
2015/08/13 Javascript
利用AJAX实现WordPress中的文章列表及评论的分页功能
2016/05/17 Javascript
学习Bootstrap滚动监听 附调用方法
2016/07/02 Javascript
Angularjs的ng-repeat中去除重复数据的方法
2016/08/05 Javascript
JS中闭包的经典用法小结(2则示例)
2016/12/28 Javascript
JQuery和HTML5 Canvas实现弹幕效果
2017/01/04 Javascript
微信小程序实战之上拉(分页加载)效果(2)
2017/04/17 Javascript
JavaScript中join()、splice()、slice()和split()函数用法示例
2018/08/24 Javascript
Python Deque 模块使用详解
2014/07/04 Python
理解Python垃圾回收机制
2016/02/12 Python
Python使用正则表达式过滤或替换HTML标签的方法详解
2017/09/25 Python
python selenium UI自动化解决验证码的4种方法
2018/01/05 Python
基于DataFrame筛选数据与loc的用法详解
2018/05/18 Python
Python面向对象进阶学习
2019/05/21 Python
Python DataFrame使用drop_duplicates()函数去重(保留重复值,取重复值)
2020/07/20 Python
最新的互联网创业计划书
2014/01/10 职场文书
大学生怎样写好自荐信
2014/02/25 职场文书
新年抽奖获奖感言
2014/03/02 职场文书
2014年党课学习材料
2014/05/11 职场文书
公司贷款承诺书
2014/05/30 职场文书
学校领导班子四风问题整改意见
2014/10/02 职场文书
2014年镇党建工作汇报材料
2014/11/02 职场文书
七年级地理教学计划
2015/01/22 职场文书
班级元旦晚会开幕词
2015/01/29 职场文书
试用期自我评价范文
2015/03/10 职场文书
投资入股协议书
2016/03/22 职场文书
Python编程根据字典列表相同键的值进行合并
2021/10/05 Python
Python安装及建立虚拟环境的完整步骤
2022/06/25 Servers