详解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做flash做的事..才完成的一个类.Auntion Action var 0.1
Feb 23 Javascript
JS 操作符整理[推荐收藏]
Nov 15 Javascript
在JavaScript中处理字符串之fontcolor()方法的使用
Jun 08 Javascript
微信小程序 教程之事件
Oct 18 Javascript
js获取json中key所对应的value值的简单方法
Jun 17 Javascript
Vue实现内部组件轮播切换效果的示例代码
Apr 07 Javascript
element-ui中的select下拉列表设置默认值方法
Aug 24 Javascript
vue图片上传本地预览组件使用详解
Feb 20 Javascript
怎样使你的 JavaScript 代码简单易读(推荐)
Apr 16 Javascript
ES6基础之字符串和函数的拓展详解
Aug 22 Javascript
vue使用nprogress实现进度条
Dec 09 Javascript
vue 封装面包屑组件教程
Nov 16 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中通过ADO调用Access数据库的方法测试不通过
2006/12/31 PHP
PHP开发规范手册之PHP代码规范详解
2011/01/13 PHP
探讨:如何使用PHP实现计算两个日期间隔的年、月、周、日数
2013/06/13 PHP
php二维数组转成字符串示例
2014/02/17 PHP
Laravel实现构造函数自动依赖注入的方法
2016/03/16 PHP
PHP数组中头部和尾部添加元素的方法(array_unshift,array_push)
2017/04/10 PHP
php中file_get_contents()函数用法实例
2019/02/21 PHP
PHP设计模式之外观模式(Facade)入门与应用详解
2019/12/13 PHP
ie8 不支持new Date(2012-11-10)问题的解决方法
2013/07/31 Javascript
当鼠标移动时出现特效的JQuery代码
2013/11/08 Javascript
js控制input输入字符解析
2013/12/27 Javascript
JavaScript中反正弦函数Math.asin()的使用简介
2015/06/14 Javascript
javascript单例模式的简单实现方法
2015/07/25 Javascript
jquery实现简单的遮罩层
2016/01/08 Javascript
JS对象创建的几种方式整理
2017/02/28 Javascript
详解vue事件对象、冒泡、阻止默认行为
2017/03/20 Javascript
mac上node.js环境的安装测试
2017/07/03 Javascript
BootStrap实现文件上传并带有进度条效果
2017/09/11 Javascript
Angularjs自定义指令实现分页插件(DEMO)
2017/09/16 Javascript
javascript系统时间设置操作示例
2019/06/17 Javascript
vue proxy 的优势与使用场景实现
2020/06/15 Javascript
JavaScript 生成唯一ID的几种方式
2021/02/19 Javascript
在Docker上部署Python的Flask框架的教程
2015/04/08 Python
Python的Django中django-userena组件的简单使用教程
2015/05/30 Python
django数据库自动重连的方法实例
2019/07/21 Python
使用python快速实现不同机器间文件夹共享方式
2019/12/22 Python
Django使用Celery加redis执行异步任务的实例内容
2020/02/20 Python
基于pandas向csv添加新的行和列
2020/05/25 Python
adidas旗下高尔夫装备供应商:TaylorMade Golf(泰勒梅高尔夫)
2016/08/28 全球购物
美国校园市场:OCM
2017/06/08 全球购物
Carolina Lemke Berlin澳大利亚官网:时尚太阳镜品牌
2019/09/17 全球购物
香港士多网上超级市场:Ztore
2021/01/09 全球购物
什么是数据库锁?Oracle中都有哪些类型的锁?
2015/08/21 面试题
大学本科毕业生求职简历的自我评价
2013/10/09 职场文书
英文自荐信常用句子
2014/03/26 职场文书
MySQL配置主从服务器(一主多从)
2021/08/07 MySQL