详解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 相关文章推荐
两个SUBMIT按钮,如何区分处理
Aug 22 Javascript
javascript showModalDialog 内跳转页面的问题
Nov 25 Javascript
判断多个input type=file是否有已经选择好文件的代码
May 23 Javascript
jQuery学习笔记 操作jQuery对象 属性处理
Sep 19 Javascript
JavaScript异步编程:异步数据收集的具体方法
Aug 19 Javascript
JavaScript中length属性的使用方法
Jun 05 Javascript
jQuery中inArray方法注意事项分析
Jan 25 Javascript
浅谈javascript中遇到的字符串对象处理
Nov 18 Javascript
简单实现js鼠标跟随效果
Aug 02 Javascript
Vue表单之v-model绑定下拉列表功能
May 14 Javascript
Vue 实现显示/隐藏层的思路(加全局点击事件)
Dec 31 Javascript
vue实现简易音乐播放器
Aug 14 Vue.js
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
经典的星际争霸,满是回忆的BGM
2020/04/09 星际争霸
确保Laravel网站不会被嵌入到其他站点中的方法
2019/10/18 PHP
php设计模式之正面模式实例分析【星际争霸游戏案例】
2020/03/24 PHP
CL vs ForZe BO5 第五场 2.13
2021/03/10 DOTA
List the Stored Procedures in a SQL Server database
2007/06/20 Javascript
js中的异常处理try...catch使用介绍
2013/09/21 Javascript
在Linux上用forever实现Node.js项目自启动
2014/07/09 Javascript
Jquery实现仿腾讯微博发表广播
2014/11/17 Javascript
WordPress中利用AJAX异步获取评论用户头像的方法
2016/01/08 Javascript
JS深度拷贝Object Array实例分析
2016/03/31 Javascript
jQuery Mobile操作HTML5的常用函数总结
2016/05/17 Javascript
浅谈angular4 ng-content 中隐藏的内容
2017/08/18 Javascript
利用vue + element实现表格分页和前端搜索的方法
2017/12/25 Javascript
vue 实现移动端键盘搜索事件监听
2019/11/06 Javascript
maptalks+three.js+vue webpack实现二维地图上贴三维模型操作
2020/08/10 Javascript
解决vue与node模版引擎的渲染标记{{}}(双花括号)冲突问题
2020/09/11 Javascript
[06:44]2014DOTA2国际邀请赛-钥匙体育馆开战 开幕式振奋人心
2014/07/19 DOTA
python使用tensorflow保存、加载和使用模型的方法
2018/01/31 Python
python机器学习之KNN分类算法
2018/08/29 Python
如何不用安装python就能在.NET里调用Python库
2019/07/12 Python
详解Django模版中加载静态文件配置方法
2019/07/21 Python
Python CVXOPT模块安装及使用解析
2019/08/01 Python
python 字典套字典或列表的示例
2019/12/16 Python
python 串口读取+存储+输出处理实例
2019/12/26 Python
Python实现计算长方形面积(带参数函数demo)
2020/01/18 Python
在tensorflow中设置保存checkpoint的最大数量实例
2020/01/21 Python
如何使用scrapy中的ItemLoader提取数据
2020/09/30 Python
Python爬虫模拟登陆哔哩哔哩(bilibili)并突破点选验证码功能
2020/12/21 Python
HTML5新表单元素_动力节点Java学院整理
2017/07/12 HTML / CSS
俄罗斯和世界各地的酒店预订:Hotels.com俄罗斯
2016/08/19 全球购物
英国知名衬衫品牌美国网站:Charles Tyrwhitt美国
2016/08/28 全球购物
迪士尼西班牙官方网上商店:ShopDisney西班牙
2020/02/02 全球购物
台湾7-ELEVEN线上购物中心:7-11
2021/01/21 全球购物
会计专业自荐信
2013/12/02 职场文书
2014年质检员工作总结
2014/11/18 职场文书
《倍数和因数》教学反思
2016/02/23 职场文书