详解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 相关文章推荐
checkbox 复选框不能为空
Jul 11 Javascript
js 设置选中行的样式的实现代码
May 24 Javascript
JQuery仿小米手机抢购页面倒计时效果
Dec 16 Javascript
js实现iGoogleDivDrag模块拖动层拖动特效的方法
Mar 04 Javascript
jQuery+Ajax+PHP弹出层异步登录效果(附源码下载)
May 27 Javascript
jquery中live()方法和bind()方法区别分析
Jun 23 Javascript
AngularJS基础 ng-selected 指令简单示例
Aug 03 Javascript
jQuery实现通过方向键控制div块上下左右移动的方法【测试可用】
Apr 26 jQuery
讲解vue-router之什么是动态路由
May 28 Javascript
微信小程序异步API为Promise简化异步编程的操作方法
Aug 14 Javascript
react 应用多入口配置及实践总结
Oct 17 Javascript
微信小程序开发之获取用户手机号码(php接口解密)
May 17 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中操作ini配置文件的方法
2013/04/25 PHP
PHP多例模式介绍
2013/06/24 PHP
php图形jpgraph操作实例分析
2017/02/22 PHP
laravel 解决ajax异步提交数据,并还回填充表格的问题
2019/10/15 PHP
TP5框架简单登录功能实现方法示例
2019/10/31 PHP
PHP copy函数使用案例代码解析
2020/09/01 PHP
Javascript学习笔记8 用JSON做原型
2010/01/11 Javascript
一个CSS+jQuery实现的放大缩小动画效果
2014/02/19 Javascript
javascript中为某个元素指定事件的三种方式
2014/08/07 Javascript
JavaScript中的ubound函数使用实例
2014/11/04 Javascript
jQuery实现渐变下拉菜单的简单方法
2015/03/11 Javascript
jquery实现网页的页面平滑滚动效果代码
2015/11/02 Javascript
AngularJS中的$watch(),$digest()和$apply()区分
2016/04/04 Javascript
Bootstrap树形菜单插件TreeView.js使用方法详解
2016/11/01 Javascript
老生常谈js中0到底是 true 还是 false
2017/03/08 Javascript
Extjs表单输入框异步校验的插件实现方法
2017/03/20 Javascript
Node.js中,在cmd界面,进入退出Node.js运行环境的方法
2018/05/12 Javascript
微信小程序实现横向增长表格的方法
2018/07/24 Javascript
详解如何在微信小程序开发中正确的使用vant ui组件
2018/09/13 Javascript
jQuery添加新内容的四个常用方法分析【append,prepend,after,before】
2019/03/19 jQuery
vue项目引入ts步骤(小结)
2019/10/31 Javascript
Javascript实现html转pdf高清版(提高分辨率)
2020/02/19 Javascript
vue 在单页面应用里使用二级套嵌路由
2020/12/19 Vue.js
Python的函数嵌套的使用方法
2014/01/24 Python
Python中使用SAX解析xml实例
2014/11/21 Python
用Python进行一些简单的自然语言处理的教程
2015/03/31 Python
Django的信号机制详解
2017/05/05 Python
中国梦演讲稿教师篇
2014/04/23 职场文书
公安个人四风问题对照检查及整改措施
2014/10/28 职场文书
财务工作个人总结
2015/02/27 职场文书
元旦晚会主持词开场白
2015/05/28 职场文书
写作指导:怎么书写竞聘演讲稿?
2019/07/04 职场文书
一文搞懂如何实现Go 超时控制
2021/03/30 Python
pandas中DataFrame检测重复值的实现
2021/05/26 Python
javascript的setTimeout()使用方法总结
2021/11/20 Javascript
解决MySQL Varchar 类型尾部空格的问题
2022/04/06 MySQL