本系列属于阮一峰老师所著的ECMAScript 6 入门学习笔记javascript
ES6以前,异步编程的方法,大概有下面四种:java
Generator函数将JavaScript异步编程带入了一个全新的阶段es6
传统的编程语言,早有异步编程的解决方案,即多任务解决方案。其中一种叫"携程"(coroutine),意思是多线程相互协做,完成异步任务编程
// yield命令成为异步两个阶段的分界线,利用yield暂停任务,进行异步操做 function* asyncJob(){ // ...其余代码 var f= yield readFile(fileA) // ...其余代码 }
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函数是自动执行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函数替换的不是表达式,而是多参数函数,将其替换成一个接受回调函数做为参数的单参数函数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
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)