Generator函数的异步应用

本系列属于阮一峰老师所著的ECMAScript 6 入门学习笔记javascript


传统方法

ES6以前,异步编程的方法,大概有下面四种:java

  • 回调函数
  • 事件监听
  • 发布/订阅
  • Promise对象

Generator函数将JavaScript异步编程带入了一个全新的阶段es6

概念

传统的编程语言,早有异步编程的解决方案,即多任务解决方案。其中一种叫"携程"(coroutine),意思是多线程相互协做,完成异步任务编程

// yield命令成为异步两个阶段的分界线,利用yield暂停任务,进行异步操做
function* asyncJob(){
  // ...其余代码
  var f= yield readFile(fileA)
  // ...其余代码
}
Generator函数的数据交换和错误处理

Generator函数能够暂停执行和恢复执行,这是它能封装异步任务的根本缘由。除此以外,它还有两个特性能够做为异步编程的完美解决方案:函数体内外数据交换和错误处理机制多线程

// next返回值的value属性,是Generator函数向外输出的数据;next还能够接收参数,向Generator函数体内输入数据
function* gen(x){
  var y = yield x + 2
  return y
}
var g = gen(1)
g.next() // {value:3,done:false}
g.next(2) // {value:2,done:false}

// Generator函数内部能够部署错误处理代码,捕获函数体外抛出的错误
function* gen(x){
  try{
    var y = yield x + 2
  }catch(e){
    console.log(e)
  }
  return y
}
var g = gen(1)
g.next()
g.throw('出错了') // 出错了
Thunk函数

Thunk函数是自动执行Generator函数的一种方法。编译器“传名调用”实现,每每是将参数放在一个临时函数中,再将这个临时函数传入函数体,这个临时函数就是Thunk函数异步

function f(m){
  return m * 2
}
f(x+5)
// 等同于
var thunk = function(){
  return x + 5
}
function f(thunk){
  return thunk() * 2
}
JavaScript语言的Thunk函数

JavaScript语言是传值调用,它的Thunk函数含义有所不一样。在JavaScript语言中,Thunk函数替换的不是表达式,而是多参数函数,将其替换成一个接受回调函数做为参数的单参数函数async

// 正常多参数数版本函数
fs.readFile(fileName,callback)

// Thunk版本单参数函数
var Thunk = function(fileName){
  return function(callback){
    return fs.readFile(fileName,callback)
  }
}
var readFileThunk = Thunk(fileName)
readFileThunk(callback)

// 任何函数,只要参数又回调函数,就能写成Thunk函数的形式
const Thunk = function(fn){
  return function(...args){
    return function(callback){
      return fn.call(this,...args,callback)
    }
  }
}
// 利用以上转换器,生成f的Thunk函数
function f(a,cb){
  cb(a)
}
const ft = Thunk(f)
ft(1)(console.log) // 1
Generator函数的流程管理

Thunk函数如今能够用于Generator函数的自动流程管理。但Thunk函数并非Generator函数自动执行的惟一方案。由于自动执行的关键是,必须有一种机制,自动控制Generator函数的流程,接收和交还程序的执行权。回调函数能够作到,Promise对象也能够作到编程语言

function run(fn){
  var gen = fn()
  function next(err,data){
    var result = gen.next(data)
    if(result.done) return
    result.value(next)
  }
  next()
}

function* g(){
  // ...
}
// run函数是一个Generator函数的自动执行器,next函数是Thunk的回调函数,result.value就是Thunk函数
run(g)
相关文章
相关标签/搜索