详解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 相关文章推荐
动态的改变IFrame的高度实现IFrame自动伸展适应高度
Dec 28 Javascript
jquery选择器的选择使用及性能介绍
Jan 16 Javascript
javascript图片相似度算法实现 js实现直方图和向量算法
Jan 14 Javascript
Bootstrap每天必学之警告框插件
Apr 26 Javascript
js 实现省市区三级联动菜单效果
Feb 20 Javascript
详解angular用$sce服务来过滤HTML标签
Apr 11 Javascript
CheckBox多选取值及判断CheckBox选中是否为空的实例
Oct 31 Javascript
VUE2 前端实现 静态二级省市联动选择select的示例
Feb 09 Javascript
VUE重点问题总结
Mar 19 Javascript
jQuery实现点击自身以外区域关闭弹出层功能完整示例【改进版】
Jul 31 jQuery
ztree加载完成后显示勾选节点的实现代码
Oct 22 Javascript
如何在JavaScript中优雅的提取循环内数据详解
Mar 04 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
把77A收信机改造成收音机
2021/03/02 无线电
PHP学习资料汇总与网址
2007/03/16 PHP
php将数据库中所有内容生成静态html文档的代码
2010/04/12 PHP
Yii框架调试心得--在页面输出执行sql语句
2014/12/25 PHP
jquery入门—选择器实现隔行变色实例代码
2013/01/04 Javascript
jQuery setTimeout()函数使用方法
2013/04/07 Javascript
JS防止用户多次提交的简单代码
2013/08/01 Javascript
javascript 3d 逐侦产品展示(核心精简)
2014/03/26 Javascript
js类定义函数时用prototype与不用的区别示例介绍
2014/06/10 Javascript
javascript实现禁止右键和F12查看源代码
2014/12/26 Javascript
Ionic实现页面下拉刷新(ion-refresher)功能代码
2016/06/03 Javascript
深入理解逻辑表达式的用法 与或非的用法
2016/06/06 Javascript
使用Web Uploader实现多文件上传
2016/06/08 Javascript
简单实现js菜单栏切换效果
2017/03/04 Javascript
详解nodejs微信jssdk后端接口
2017/05/25 NodeJs
jQuery实现购物车的总价计算和总价传值功能
2018/11/28 jQuery
小程序自定义模板实现吸顶功能
2020/01/08 Javascript
[01:29:42]Liquid vs VP Supermajor决赛 BO 第一场 6.10
2018/07/05 DOTA
深入解析Python中的lambda表达式的用法
2015/08/28 Python
Django的信号机制详解
2017/05/05 Python
django之session与分页(实例讲解)
2017/11/13 Python
Python实现按特定格式对文件进行读写的方法示例
2017/11/30 Python
Python基于numpy模块实现回归预测
2020/05/14 Python
使用python实现时间序列白噪声检验方式
2020/06/03 Python
python opencv 实现读取、显示、写入图像的方法
2020/06/08 Python
CSS3 画基本图形,圆形、椭圆形、三角形等
2016/09/20 HTML / CSS
什么是.net
2015/08/03 面试题
小区停车场管理制度
2014/01/27 职场文书
2014年清明节网上祭英烈寄语
2014/04/09 职场文书
工厂门卫的岗位职责
2014/07/27 职场文书
班子四风对照检查材料
2014/08/21 职场文书
勿忘国耻9.18演讲稿(经典篇)
2014/09/14 职场文书
解除劳动合同协议书
2014/09/17 职场文书
团员个人总结
2015/02/26 职场文书
2015年教师节广播稿
2015/08/19 职场文书
Spring Data JPA使用JPQL与原生SQL进行查询的操作
2021/06/15 Java/Android