详解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 相关文章推荐
动态为事件添加js代码示例
Feb 15 Javascript
safari,opera嵌入iframe页面cookie读取问题解决方法
Jun 23 Javascript
JS如何将UTC格式时间转本地格式
Sep 04 Javascript
简单时间提示DEMO从0开始一直进行计时
Nov 19 Javascript
jquery内置验证(validate)使用方法示例(表单验证)
Dec 04 Javascript
详解javascript事件绑定使用方法
Oct 20 Javascript
前端axios下载excel文件(二进制)的处理方法
Jul 31 Javascript
详解VUE里子组件如何获取父组件动态变化的值
Dec 26 Javascript
ES6函数和数组用法实例分析
May 23 Javascript
vue 点击其他区域关闭自定义div操作
Jul 17 Javascript
js闭包和垃圾回收机制示例详解
Mar 01 Javascript
一文了解JavaScript用Element Traversal新属性遍历子元素
Nov 27 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下连接ftp实现文件的上传、下载、删除文件实例代码
2010/06/03 PHP
PHP基础陷阱题(变量赋值)
2012/09/12 PHP
php上传apk后自动提取apk包信息的使用(示例下载)
2013/04/26 PHP
PHP内置的Math函数效率测试
2014/12/01 PHP
Yii多表联合查询操作详解
2016/06/02 PHP
Javascript实例教程(19) 使用HoTMetal(3)
2006/12/23 Javascript
文本框中,回车键触发事件的js代码[多浏览器兼容]
2010/06/07 Javascript
jquery 全局AJAX事件使用代码
2010/11/05 Javascript
使用jQuery重置(reset)表单的方法
2014/05/05 Javascript
jQuery定义背景动态切换效果的方法
2015/03/23 Javascript
Java与JavaScript中判断两字符串是否相等的区别
2017/03/13 Javascript
JavaScript定义函数_动力节点Java学院整理
2017/06/27 Javascript
对于Javascript 执行上下文的全面了解
2017/09/05 Javascript
一篇文章介绍redux、react-redux、redux-saga总结
2019/05/23 Javascript
jQuery操作事件完整实例分析
2020/01/10 jQuery
jQuery 动画与停止动画效果实例详解
2020/05/19 jQuery
python socket 超时设置 errno 10054
2014/07/01 Python
python下os模块强大的重命名方法renames详解
2017/03/07 Python
pandas ix &iloc &loc的区别
2019/01/10 Python
使用Python正则表达式操作文本数据的方法
2019/05/14 Python
Django ImageFiled上传照片并显示的方法
2019/07/28 Python
Python使用Chrome插件实现爬虫过程图解
2020/06/09 Python
8种常用的Python工具
2020/08/05 Python
css3 按钮样式简单可扩展创建
2013/03/18 HTML / CSS
5 个强大的HTML5 API 函数推荐
2014/11/19 HTML / CSS
Skyscanner澳大利亚:全球领先的旅游搜索网站
2018/03/24 全球购物
JAKO-O德国野酷台湾站:德国首屈一指的婴幼童用品品牌
2019/01/14 全球购物
Envie de Fraise意大利:法国网上推出的孕妇装品牌
2020/10/18 全球购物
销售员自我评价怎么写
2013/09/19 职场文书
4s店活动策划方案
2014/08/25 职场文书
销售顾问工作计划书
2014/09/15 职场文书
2014最新预备党员思想汇报范文:中国梦,我的梦
2014/10/25 职场文书
幼儿园小班家长评语
2014/12/30 职场文书
5.12护士节活动总结
2015/02/10 职场文书
无故旷工检讨书
2015/08/15 职场文书
Python实现文字pdf转换图片pdf效果
2022/04/03 Python