引自http://es6.ruanyifeng.com/#docs/generator#yield--表达式

1.常用的回调方法

  1. step1(function (value1) {
  2. step2(value1, function(value2) {
  3. step3(value2, function(value3) {
  4. step4(value3, function(value4) {
  5. // Do something with value4
  6. });
  7. });
  8. });
  9. });

2.ES6中的Promise

  1. Promise.resolve(step1)
  2. .then(step2)
  3. .then(step3)
  4. .then(step4)
  5. .then(function (value4) {
  6. // Do something with value4
  7. }, function (error) {
  8. // Handle any error from step1 through step4
  9. })
  10. .done();

3.Generator同步的方法

  1. function* longRunningTask(value1) {
  2. try {
  3. var value2 = yield step1(value1);
  4. var value3 = yield step2(value2);
  5. var value4 = yield step3(value3);
  6. var value5 = yield step4(value4);
  7. // Do something with value4
  8. } catch (e) {
  9. // Handle any error from step1 through step4
  10. }
  11.  
  12. scheduler(longRunningTask(initialValue));
  13.  
  14. function scheduler(task) {
  15. var taskObj = task.next(task.value);
  16. // 如果Generator函数未结束,就继续调用
  17. if (!taskObj.done) {
  18. task.value = taskObj.value
  19. scheduler(task);
  20. }
  21. }

另一种方法

  1. let steps = [step1Func, step2Func, step3Func];
  2.  
  3. function *iterateSteps(steps){
  4. for (var i=; i< steps.length; i++){
  5. var step = steps[i];
  6. yield step();
  7. }
  8. }

4.Generator异步

  1. function run(fn) {
  2. var gen = fn();
  3.  
  4. function next(err, data) {
  5. var result = gen.next(data);
  6. if (result.done) return;
  7. result.value(next);
  8. }
  9.  
  10. next();
  11. }
  1. var g = function* (){
  2. var f1 = yield readFile('fileA');
  3. var f2 = yield readFile('fileB');
  4. // ...
  5. var fn = yield readFile('fileN');
  6. };
  7. run(g);
  1.  

5.async

  1. var asyncReadFile = async function () {
  2. var f1 = await readFile('/etc/fstab');
  3. var f2 = await readFile('/etc/shells');
  4. console.log(f1.toString());
  5. console.log(f2.toString());
  6. };

async函数对 Generator 函数的改进,体现在以下四点。

(1)内置执行器。

Generator 函数的执行必须靠执行器,所以才有了co模块,而async函数自带执行器。也就是说,async函数的执行,与普通函数一模一样,只要一行。

  1. var result = asyncReadFile();

上面的代码调用了asyncReadFile函数,然后它就会自动执行,输出最后结果。这完全不像 Generator 函数,需要调用next方法,或者用co模块,才能真正执行,得到最后结果。

(2)更好的语义。

asyncawait,比起星号和yield,语义更清楚了。async表示函数里有异步操作,await表示紧跟在后面的表达式需要等待结果。

(3)更广的适用性。

co模块约定,yield命令后面只能是 Thunk 函数或 Promise 对象,而async函数的await命令后面,可以是Promise 对象和原始类型的值(数值、字符串和布尔值,但这时等同于同步操作)。

(4)返回值是 Promise。

async函数的返回值是 Promise 对象,这比 Generator 函数的返回值是 Iterator 对象方便多了。你可以用then方法指定下一步的操作。

进一步说,async函数完全可以看作多个异步操作,包装成的一个 Promise 对象,而await命令就是内部then命令的语法糖。

demo:

我们通过一个例子,来看 async 函数与 Promise、Generator 函数的比较。

假定某个 DOM 元素上面,部署了一系列的动画,前一个动画结束,才能开始后一个。如果当中有一个动画出错,就不再往下执行,返回上一个成功执行的动画的返回值。

首先是 Promise 的写法。

  1. function chainAnimationsPromise(elem, animations) {
  2.  
  3. // 变量ret用来保存上一个动画的返回值
  4. var ret = null;
  5.  
  6. // 新建一个空的Promise
  7. var p = Promise.resolve();
  8.  
  9. // 使用then方法,添加所有动画
  10. for(var anim of animations) {
  11. p = p.then(function(val) {
  12. ret = val;
  13. return anim(elem);
  14. });
  15. }
  16.  
  17. // 返回一个部署了错误捕捉机制的Promise
  18. return p.catch(function(e) {
  19. /* 忽略错误,继续执行 */
  20. }).then(function() {
  21. return ret;
  22. });
  23.  
  24. }

接着是 Generator 函数的写法。

  1. function chainAnimationsGenerator(elem, animations) {
  2.  
  3. return spawn(function*() {
  4. var ret = null;
  5. try {
  6. for(var anim of animations) {
  7. ret = yield anim(elem);
  8. }
  9. } catch(e) {
  10. /* 忽略错误,继续执行 */
  11. }
  12. return ret;
  13. });
  14.  
  15. }

最后是 async 函数的写法。

  1. async function chainAnimationsAsync(elem, animations) {
  2. var ret = null;
  3. try {
  4. for(var anim of animations) {
  5. ret = await anim(elem);
  6. }
  7. } catch(e) {
  8. /* 忽略错误,继续执行 */
  9. }
  10. return ret;
  11. }

js中控制流管理的四种方法的更多相关文章

  1. js中判断数据类型的四种方法总结

    js中判断数据类型的四种方法 前言 在js中,我们经常需要判断数据的类型,那么哪些方法可以用来判断数据的类型呢?哪种方法判断数据类型最准确呢? 我们来一个个分析: 1.typeof typeof是一个 ...

  2. JS 中检测数组的四种方法

    今天和大家分享一下 JS 中检测是不是数组的四种方法,虽然篇幅不长,不过方法应该算是比较全面了. 1. instanceof 方法 instanceof 用于检测一个对象是不是某个类的实例,数组也是一 ...

  3. JS中检测数据类型的四种方法

    1.typeof 用来检测数据类型的运算符->typeof value->返回值首先是一个字符串,其次里面包含了对应的数据类型,例如:"number"."st ...

  4. JS去除数组中重复值的四种方法

    JS去除数组中重复值的四种方法 1 /// <summary>            o[this[i]] = "";  }      }       newArr.p ...

  5. js中数组去重的几种方法

    js中数组去重的几种方法         1.遍历数组,一一比较,比较到相同的就删除后面的                 function unique(arr){                 ...

  6. PHP从数组中删除元素的四种方法实例

    PHP从数组中删除元素的四种方法实例 一.总结 一句话总结:unset(),array_splice(),array_diff(),array_diff_key() 二.PHP从数组中删除元素的四种方 ...

  7. IOS中Json解析的四种方法

    作为一种轻量级的数据交换格式,json正在逐步取代xml,成为网络数据的通用格式. 有的json代码格式比较混乱,可以使用此“http://www.bejson.com/”网站来进行JSON格式化校验 ...

  8. 【转】IOS中Json解析的四种方法

    原文网址:http://blog.csdn.net/enuola/article/details/7903632 作为一种轻量级的数据交换格式,json正在逐步取代xml,成为网络数据的通用格式. 有 ...

  9. Js中数据类型判断的几种方法

    判断js中的数据类型有一下几种方法:typeof.instanceof. constructor. prototype. $.type()/jquery.type(),接下来主要比较一下这几种方法的异 ...

随机推荐

  1. lvs负载均衡连接

    http://blog.csdn.net/zwz1984/article/details/45194377 http://blog.csdn.net/zwz1984/article/details/4 ...

  2. [笔记]Laravel TDD 胡乱记录

    TDD: 测试驱动开发(Test-Driven Development),TDD的原理是在开发功能代码之前,先编写单元测试用例代码,测试代码确定需要编写什么产品代码. -- 载自TDD百度百科 参考 ...

  3. CF774L Bars

    题意:给你一个二进制表示是否可以吃巧克力.一共有k个巧克力,第一天和最后一天必须吃.最小化每两次吃巧克力的最大间隔? 标程: #include<bits/stdc++.h> using n ...

  4. leetcode-第10周双周赛-5080-查找两颗二叉搜索树之和

    题目描述: 自己的提交: class Solution: def twoSumBSTs(self, root1: TreeNode, root2: TreeNode, target: int) -&g ...

  5. dos中文乱码怎么办?

    最简单的方法: 通过 chcp命令改变代码页,UTF-8的代码页为65001 即chcp 65001 chcp 65001  就是换成UTF-8代码页 chcp 936 可以换回默认的GBK chcp ...

  6. 树的直径+质因子——好题!cf1101D

    /* 因为质因子很少 状态转移时用dp[u][i]表示结点u的第i个质因子所在的最大深度即可 等价于带限制的求直径 */ #include<bits/stdc++.h> #include& ...

  7. class.forname & classloader

    From https://www.cnblogs.com/gaojing/archive/2012/03/15/2413638.html 传统的使用jdbc来访问数据库的流程为: Class.forN ...

  8. 设置IDEA自动提示补全代码,关于idea自动补全的详细设置。

    在IDEA中,默认的代码自动提示不够智能,现在配置成更加智能的方式. File-Settings-Editor-General-Code Completion中 把最上面的大小写敏感度改成none,下 ...

  9. LightOJ-1259-Goldbach`s Conjecture-素数打表+判断素数对数

    Goldbach's conjecture is one of the oldest unsolved problems in number theory and in all of mathemat ...

  10. import time 进度条动态输出26个字母

    # 2018-08-06 19:42:51 import time # 调用时间模块 num = 97 # 字母a while num <= 115: # print(chr(num), end ...