JavaScript异步问题Generator 函数

异步问题的产生

JavaScript只有一个线程,要实现复杂的功能异步编程尤为重要
JavaScript 语言实现异步编程,就是使用回调函数(callback)
但是如果多个回调函数嵌套则会导致代码横向发展,难以管理

解决办法

1. Promise

是一种新的写法,允许将回调函数的横向加载,改成纵向加载.Promise 提供 then 方法加载回调函数,catch方法捕捉执行过程中抛出的错误

var readFile = require('fs-readfile-promise');

readFile(fileA)
.then(function(data){
  console.log(data.toString());
})
.then(function(){
  return readFile(fileB);
})
.then(function(data){
  console.log(data.toString());
})
.catch(function(err) {
  console.log(err);
});

代码中使用了 fs-readfile-promise 模块,它的作用就是返回一个 Promise 版本的 readFile 函数

然而Promise 的最大问题是代码冗余

2. 传统的异步解决办法-协程

协程是多个线程互相协作,完成异步任务

function asnycJob() {
  // ...
  var f = yield readFile(fileA);
  // ...
}

其中的 yield 命令。它表示执行到此处,执行权将交给其他协程。
yield 命令是异步两个阶段的分界线。

协程遇到 yield 命令就暂停,等到执行权返回,再从暂停的地方继续往后执行。它的最大优点,就是代码的写法非常像同步操作

Generator 函数

Generator 函数就是 协程 在 ES6 的实现,最大特点就是可以交出函数的执行权.整个 Generator 函数就是一个封装的异步任务,或者说是异步任务的容器。异步操作需要暂停的地方,都要用 yield 语句注明

function* gen(x){
  var y = yield x + 2;
  return y;
}

上述Generator 函数的执行方法如下

var g = gen(1);
g.next() // { value: 3, done: false }
g.next() // { value: undefined, done: true }

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

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


  • (yield表达式只能用在 Generator 函数里面,用在其他地方都会报错)

Generator 函数可以暂停执行和恢复执行,这是它能封装异步任务的根本原因

http://www.ruanyifeng.com/blog/2015/04/generator.html

猜你喜欢

转载自blog.csdn.net/weixin_33755557/article/details/86918442
今日推荐