详解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 判断用户输入的邮箱及手机格式是否正确
Dec 08 Javascript
js数值和和字符串进行转换时可以对不同进制进行操作
Mar 05 Javascript
js对象继承之原型链继承实例
Jan 10 Javascript
jQuery实现进度条效果代码
Dec 17 Javascript
基于jquery编写的放大镜插件
Mar 23 Javascript
JS简单获取及显示当前时间的方法
Aug 03 Javascript
浅谈Vue网络请求之interceptors实际应用
Feb 28 Javascript
layui table设置前台过滤转义等方法
Aug 17 Javascript
JQuery获取可视区尺寸和文档尺寸及制作悬浮菜单示例
May 14 jQuery
JavaScript实现图片放大镜效果
Jun 27 Javascript
浅谈Vue 自动化部署打包上线
Jun 14 Javascript
vue实现路由懒加载的3种方法示例
Sep 01 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
收听短波不可能有声音清晰的品质吗
2021/03/01 无线电
PHP无限分类(树形类)的深入分析
2013/06/02 PHP
javascript权威指南 学习笔记之变量作用域分享
2011/09/28 Javascript
JS实现定时自动关闭DIV层提示框的方法
2015/05/11 Javascript
详解JavaScript中双等号引起的隐性类型转换
2016/05/30 Javascript
AngularJS中的API(接口)简单实现
2016/07/28 Javascript
jQuery旋转插件jqueryrotate用法详解
2016/10/13 Javascript
jQuery图片缩放插件smartZoom使用实例详解
2017/08/25 jQuery
js的函数的按值传递参数(实例讲解)
2017/11/16 Javascript
使用React代码动态生成栅格布局的方法
2020/05/24 Javascript
微信小程序tab左右滑动切换功能的实现代码
2021/02/08 Javascript
[59:48]DOTA2-DPC中国联赛 正赛 VG vs Magma BO3 第一场 1月26日
2021/03/11 DOTA
Python使用Supervisor来管理进程的方法
2015/05/28 Python
python实现在pandas.DataFrame添加一行
2018/04/04 Python
kaggle+mnist实现手写字体识别
2018/07/26 Python
OpenCV+python手势识别框架和实例讲解
2018/08/03 Python
Python 3.6 中使用pdfminer解析pdf文件的实现
2019/09/25 Python
Python matplotlib以日期为x轴作图代码实例
2019/11/22 Python
Python语法之精妙的十个知识点(装B语法)
2020/01/18 Python
python统计字符串中字母出现次数代码实例
2020/03/02 Python
Python基于DB-API操作MySQL数据库过程解析
2020/04/23 Python
Python sorted对list和dict排序
2020/06/09 Python
Python urllib3软件包的使用说明
2020/11/18 Python
Bonami斯洛伐克:购买家具和家居饰品
2019/07/02 全球购物
通信工程专业个人找工作求职信范文
2013/09/21 职场文书
写好自荐信的要点
2013/11/06 职场文书
就业自荐信
2013/12/04 职场文书
小学国庆节活动方案
2014/02/11 职场文书
大学生学年个人总结
2015/02/15 职场文书
住房公积金贷款工资证明
2015/06/12 职场文书
朋友离别感言
2015/08/04 职场文书
家电创业计划书
2019/08/05 职场文书
2019大学生暑期实习心得总结
2019/08/21 职场文书
导游词之河姆渡遗址博物馆
2019/10/10 职场文书
Python实现抖音热搜定时爬取功能
2022/03/16 Python
win11如何查看端口是否被占用? Win11查看端口是否占用的技巧
2022/04/05 数码科技