详解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 parseInt("08")未指定进位制问题
Jun 19 Javascript
JavaScript学习笔记之取数组中最大值和最小值
Mar 23 Javascript
jQuery+HTML5实现弹出创意搜索框层
Dec 29 Javascript
利用JS实现简单的瀑布流加载图片效果
Apr 22 Javascript
微信小程序获取用户openId的实现方法
May 23 Javascript
JSON在Javascript中的使用(eval和JSON.parse的区别)详细解析
Sep 05 Javascript
使用 Node.js 模拟滑动拼图验证码操作的示例代码
Nov 02 Javascript
Vue核心概念Action的总结
Jan 18 Javascript
利用vue重构有赞商城的思路以及总结整理
Feb 21 Javascript
详解vue在项目中使用百度地图
Mar 26 Javascript
JS Generator 函数的含义与用法实例总结
Apr 08 Javascript
Element Input输入框的使用方法
Jul 26 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之数据库操作详解及乱码解决!
2007/01/02 PHP
PHP常见的序列化与反序列化操作实例分析
2019/10/28 PHP
JavaScript 判断浏览器类型及版本
2009/02/21 Javascript
一些Javascript的IE和Firefox(火狐)兼容性的问题总结及常用例子
2009/05/21 Javascript
asp(javascript)全角半角转换代码 dbc2sbc
2009/08/06 Javascript
jQuery生成asp.net服务器控件的代码
2010/02/04 Javascript
javascript实现的像java、c#之类的sleep暂停的函数代码
2010/03/04 Javascript
js post方式传递提交的实现代码
2010/05/31 Javascript
jQuery实现的一个自定义Placeholder属性插件
2014/08/11 Javascript
Js 正则表达式知识汇总
2014/12/02 Javascript
JQuery显示隐藏页面元素的方法总结
2015/04/16 Javascript
JavaScript+html5 canvas实现图片破碎重组动画特效
2016/02/22 Javascript
BootStrap 智能表单实战系列(十)自动完成组件的支持
2016/06/13 Javascript
Node.js 文件夹目录结构创建实例代码
2016/07/08 Javascript
BootStrap Fileinput初始化时的一些参数
2016/12/30 Javascript
jQuery无刷新上传之uploadify简单代码
2017/01/17 Javascript
jQuery中event.target和this的区别详解
2020/08/13 jQuery
vue监听滚动事件的方法
2020/12/21 Vue.js
python实现apahce网站日志分析示例
2014/04/02 Python
Python输出汉字字库及将文字转换为图片的方法
2016/06/04 Python
Python3中类、模块、错误与异常、文件的简易教程
2017/11/20 Python
python tensorflow学习之识别单张图片的实现的示例
2018/02/09 Python
解决python3 pika之连接断开的问题
2018/12/18 Python
pytorch使用指定GPU训练的实例
2019/08/19 Python
tensorflow2.0与tensorflow1.0的性能区别介绍
2020/02/07 Python
Python3与fastdfs分布式文件系统如何实现交互
2020/06/23 Python
Python 实现一个计时器
2020/07/28 Python
Python Pillow(PIL)库的用法详解
2020/09/19 Python
python使用bs4爬取boss直聘静态页面
2020/10/10 Python
几个常见的软件测试问题
2016/09/07 面试题
奖学金自我鉴定范文
2013/10/03 职场文书
市场营销策划方案
2014/06/11 职场文书
班子成员四风问题自我剖析材料
2014/09/29 职场文书
大学生实习证明
2015/06/16 职场文书
2016年社区中秋节活动总结
2016/04/05 职场文书
html中两种获取标签内的值的方法
2022/06/10 HTML / CSS