ECMAScript 6(ES6) 特性概览和与ES5的比较14(下)-生成器Generators

十四.Generator生成器

4.生成器控制流

支持生成器,迭代器的特殊情况,其中控制流可以暂停和恢复,以便支持与“协同例程”结合Promise的异步编程(见下文)。 [注意:通用异步函数通常由可重用的库提供,这里只是为了更好地理解。 在实践中见co或Bluebird的协程。]

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

协程有点像函数,又有点像线程。它的运行流程大致如下。
第一步,协程A开始执行。
第二步,协程A执行到一半,进入暂停,执行权转移到协程B。
第三步,(一段时间后)协程B交还执行权。
第四步,协程A恢复执行。
上面流程的协程A,就是异步任务,因为它分成两段(或多段)执行。
举例来说,读取文件的协程写法如下。

function* asyncJob() {
  // ...其他代码
  var f = yield readFile(fileA);
  // ...其他代码
}

上面代码的函数asyncJob是一个协程,它的奥妙就在其中的yield命令。它表示执行到此处,执行权将交给其他协程。也就是说,yield命令是异步两个阶段的分界线。

协程遇到yield命令就暂停,等到执行权返回,再从暂停的地方继续往后执行。它的最大优点,就是代码的写法非常像同步操作,如果去除yield命令,简直一模一样。
—摘自ECMAScript 6 入门 阮一峰

ECMAScript 6

//通用异步控制流驱动程序
function async (proc, ...params) {
    let iterator = proc(...params)
    return new Promise((resolve, reject) => {
        let loop = (value) => {
            let result
            try {
                result = iterator.next(value)
            }
            catch (err) {
                reject(err)
            }
            if (result.done)
                resovle(result.value)
            else if ( typeof result.value === "object" && 
                      typeof result.value.then === "function")
                result.value.then((value) => {
                    loop()
                },(err) => {
                    reject(err)
                })
            else
                loop(result.value)
        }
        loop()
    })
}

//特定的应用程序异步构建
function makeAsync (text, after) {
    return new Promise((resolve, reject) =>{
        setTimeout(() => resolve(text),after)
    })
}

//特定的应用程序异步过程
async(function* (greeting) {
   let foo = yield makeAsync("foo", 300)
   let bar = yield makeAsync("bar", 200)
   let baz = yield makeAsync("bar", 100)
   return `${greeting} ${foo} ${bar} ${baz}`
},"Hello").then((msg) => {
    console.log("RESULT:", msg) //"Hello foo bar baz"
})

ECMAScript 5

//ES5中没有响应的表达方式

5.生成器方法

基于生成器函数支持生成器方法,即类和对象中的方法。

ECMAScript 6

class Clz {
    * bar () {
        ...
    }
}
let Obj = {
    * foo () {
        ...
    }
}

ECMAScript 5

//ES5中没有响应的表达方式

猜你喜欢

转载自blog.csdn.net/u010622874/article/details/84035896