博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
由迭代器到js异步操作
阅读量:7235 次
发布时间:2019-06-29

本文共 3477 字,大约阅读时间需要 11 分钟。

什么是迭代器?

一个简单的列子

function makeIterator (arr) {    let nextIndex = 0;    //返回一个迭代器方法    return {        next: () => {            if(nextIndex < arr.length){                return {
value: arr[nextIndex++], done: false} }else{ return {
done: true} } } }}const it = makeIterator([1,2,3]);console.log('1:', it.next());console.log('2:', it.next());console.log('3:', it.next());console.log('end:', it.next());复制代码

执行结果:

1: {value: 1, done: false}2: {value: 2, done: false}3: {value: 3, done: false}end: {
done: true}复制代码

上述为一个简单的迭代器,因为迭代器的代码过于繁琐,产生了生成器即Generator

什么是生成器?

较为简单的理解,生成器会返回一个迭代器,简化了代码,下面为一个生成器的列子。

function *makeIterator (arr) {    for(let i = 0; i < arr.length; i++){        yield arr[i];    }}const gen = makeIterator(['a','b','c']);console.log('1', gen.next());console.log('2', gen.next());console.log('3', gen.next());console.log('end', gen.next());复制代码

执行结果和上述相同:

1: {value: 1, done: false}2: {value: 2, done: false}3: {value: 3, done: false}end: {
done: true}复制代码

有了上述关于迭代器和生成器的概念,我们来看下关于js的异步操作。

文件目录结构如下async│     └───content.js└───asyncRead.js复制代码

content.js:

const content = '此js为测试js';复制代码
  1. 普通的js回调
const fs = require('fs');function readFile(cb){    fs.readFile('./content.js', (err, data) => {        if(err) return cb(err);        cb && cb(null,data);    })}//1. 回调函数readFile((err, data) => {    if(!err){        //返回的是buffer类型        console.log('data:', data);        //返回正常内容        console.log('data.toString():', data.toString);    }else{        console.log('err:', err);    }})复制代码
  1. promise
const fs = require(fs);function readFileAsync(path) {    //定义了一个执行器    return new Promise((resolve, reject) => {        fs.readFile(path, (err, data) => {            if(err) reject(err);            else resolve(data);        })    })}readFileAsync('./content.js')    .then(data => {        console.log('data:', data.toString());    })    .catch(err => {        console.log('err:', err);    })复制代码
  1. co + Generator + Promise 生成器的方法
const fs = require(fs);const co = require('co');const util = require('util');const readFileFunc = util.promisify(fs.readFile);co(function *(){    let data = yield readFileFunc('./content.js');    data = data.toString();    console.log('data:', data);})复制代码
  1. async await (为Generator的语法糖,更加语义化)
const fs = require('fs');const util = require('util');const readAsync = util.promisify(fs.readFile);async function init() {    let data = await readAsync('./content.js');    console.log('dataToString:', data.toString())}init()复制代码

关于生成器原理的一点补充:

先看一个简单的例子:

function *gen(x){    var y = yield x + 2;    return y}var g = gen(1);console.log(g.next());console.log(g.next());复制代码

输出结果:

Object {value: 3, done: false}Object {value: undefined, done: true}复制代码

分析上述执行结果:

调用generator函数,会产生一个内部指针(遍历器)g,这是 Generator 函数不同于普通函数的另一个地方,即执行它不会返回结果,返回的是指针对象。调用指针 g 的 next 方法,会移动内部指针(即执行异步任务的第一段),指向第一个遇到的 yield 语句,上例是执行到 x + 2 为止。

换言之,next 方法的作用是分阶段执行 Generator 函数。每次调用 next 方法,会返回一个对象,表示当前阶段的信息( value 属性和 done 属性)。value 属性是 yield 语句后面表达式的值,表示当前阶段的值;done 属性是一个布尔值,表示 Generator 函数是否执行完毕,即是否还有下一个阶段。

稍微复杂一点的实例:

var fetch = require('node-fetch');//生成器function* gen(){  var url = 'https://api.github.com/users/github';  var result = yield fetch(url);  console.log(result.bio);}//gen()函数生成一个内部指针var g = gen();//执行next()方法,执行到yield交出执行权var result = g.next();//拿到返回结果,以为fetch返回的是promise对象,后面进行promise处理result.value.then(function(data){  return data.json();}).then(function(data){  g.next(data);});复制代码

参考链接:

转载地址:http://rvlfm.baihongyu.com/

你可能感兴趣的文章
Android-Rxjava+Retrofit2.x 获取Http状态码、响应头(Headers)等数据
查看>>
swift版indexOfObject()
查看>>
第二十九章:基于SpringBoot平台使用Lombok来优雅的编码
查看>>
第三章:SpringBoot使用SpringDataJPA完成CRUD
查看>>
React + Redux + react router技术栈架构
查看>>
Android任务队列使用
查看>>
Swift语法对编译速度的影响
查看>>
如何在Python下搭建QT+SIP+PyQt5环境
查看>>
说说在 Linux 中如何查看系统信息
查看>>
iphone 常用的app info plist设置
查看>>
快速排序算法的实现
查看>>
排序面试 java版
查看>>
python-16-元类和异常
查看>>
2017 JavaScript 主流框架性能总结
查看>>
Class详解
查看>>
正则:此处用到字符串的replace方法
查看>>
什么是css?
查看>>
webpack 打包多页面
查看>>
傻瓜式入门Redux
查看>>
最新图解 如何提升phpstudy中的mysql版本
查看>>