js中控制流管理的四种方法
引自http://es6.ruanyifeng.com/#docs/generator#yield--表达式
1.常用的回调方法
- step1(function (value1) {
- step2(value1, function(value2) {
- step3(value2, function(value3) {
- step4(value3, function(value4) {
- // Do something with value4
- });
- });
- });
- });
2.ES6中的Promise
- Promise.resolve(step1)
- .then(step2)
- .then(step3)
- .then(step4)
- .then(function (value4) {
- // Do something with value4
- }, function (error) {
- // Handle any error from step1 through step4
- })
- .done();
3.Generator同步的方法
- function* longRunningTask(value1) {
- try {
- var value2 = yield step1(value1);
- var value3 = yield step2(value2);
- var value4 = yield step3(value3);
- var value5 = yield step4(value4);
- // Do something with value4
- } catch (e) {
- // Handle any error from step1 through step4
- }
- scheduler(longRunningTask(initialValue));
- function scheduler(task) {
- var taskObj = task.next(task.value);
- // 如果Generator函数未结束,就继续调用
- if (!taskObj.done) {
- task.value = taskObj.value
- scheduler(task);
- }
- }
另一种方法
- let steps = [step1Func, step2Func, step3Func];
- function *iterateSteps(steps){
- for (var i=; i< steps.length; i++){
- var step = steps[i];
- yield step();
- }
- }
4.Generator异步
- function run(fn) {
- var gen = fn();
- function next(err, data) {
- var result = gen.next(data);
- if (result.done) return;
- result.value(next);
- }
- next();
- }
var g = function* (){
var f1 = yield readFile('fileA');
var f2 = yield readFile('fileB');
// ...
var fn = yield readFile('fileN');
};
run(g);
5.async
- var asyncReadFile = async function () {
- var f1 = await readFile('/etc/fstab');
- var f2 = await readFile('/etc/shells');
- console.log(f1.toString());
- console.log(f2.toString());
- };
async
函数对 Generator 函数的改进,体现在以下四点。
(1)内置执行器。
Generator 函数的执行必须靠执行器,所以才有了co
模块,而async
函数自带执行器。也就是说,async
函数的执行,与普通函数一模一样,只要一行。
var result = asyncReadFile();
上面的代码调用了asyncReadFile
函数,然后它就会自动执行,输出最后结果。这完全不像 Generator 函数,需要调用next
方法,或者用co
模块,才能真正执行,得到最后结果。
(2)更好的语义。
async
和await
,比起星号和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 的写法。
- function chainAnimationsPromise(elem, animations) {
- // 变量ret用来保存上一个动画的返回值
- var ret = null;
- // 新建一个空的Promise
- var p = Promise.resolve();
- // 使用then方法,添加所有动画
- for(var anim of animations) {
- p = p.then(function(val) {
- ret = val;
- return anim(elem);
- });
- }
- // 返回一个部署了错误捕捉机制的Promise
- return p.catch(function(e) {
- /* 忽略错误,继续执行 */
- }).then(function() {
- return ret;
- });
- }
接着是 Generator 函数的写法。
- function chainAnimationsGenerator(elem, animations) {
- return spawn(function*() {
- var ret = null;
- try {
- for(var anim of animations) {
- ret = yield anim(elem);
- }
- } catch(e) {
- /* 忽略错误,继续执行 */
- }
- return ret;
- });
- }
最后是 async 函数的写法。
- async function chainAnimationsAsync(elem, animations) {
- var ret = null;
- try {
- for(var anim of animations) {
- ret = await anim(elem);
- }
- } catch(e) {
- /* 忽略错误,继续执行 */
- }
- return ret;
- }
js中控制流管理的四种方法的更多相关文章
- js中判断数据类型的四种方法总结
js中判断数据类型的四种方法 前言 在js中,我们经常需要判断数据的类型,那么哪些方法可以用来判断数据的类型呢?哪种方法判断数据类型最准确呢? 我们来一个个分析: 1.typeof typeof是一个 ...
- JS 中检测数组的四种方法
今天和大家分享一下 JS 中检测是不是数组的四种方法,虽然篇幅不长,不过方法应该算是比较全面了. 1. instanceof 方法 instanceof 用于检测一个对象是不是某个类的实例,数组也是一 ...
- JS中检测数据类型的四种方法
1.typeof 用来检测数据类型的运算符->typeof value->返回值首先是一个字符串,其次里面包含了对应的数据类型,例如:"number"."st ...
- JS去除数组中重复值的四种方法
JS去除数组中重复值的四种方法 1 /// <summary> o[this[i]] = ""; } } newArr.p ...
- js中数组去重的几种方法
js中数组去重的几种方法 1.遍历数组,一一比较,比较到相同的就删除后面的 function unique(arr){ ...
- PHP从数组中删除元素的四种方法实例
PHP从数组中删除元素的四种方法实例 一.总结 一句话总结:unset(),array_splice(),array_diff(),array_diff_key() 二.PHP从数组中删除元素的四种方 ...
- IOS中Json解析的四种方法
作为一种轻量级的数据交换格式,json正在逐步取代xml,成为网络数据的通用格式. 有的json代码格式比较混乱,可以使用此“http://www.bejson.com/”网站来进行JSON格式化校验 ...
- 【转】IOS中Json解析的四种方法
原文网址:http://blog.csdn.net/enuola/article/details/7903632 作为一种轻量级的数据交换格式,json正在逐步取代xml,成为网络数据的通用格式. 有 ...
- Js中数据类型判断的几种方法
判断js中的数据类型有一下几种方法:typeof.instanceof. constructor. prototype. $.type()/jquery.type(),接下来主要比较一下这几种方法的异 ...
随机推荐
- lvs负载均衡连接
http://blog.csdn.net/zwz1984/article/details/45194377 http://blog.csdn.net/zwz1984/article/details/4 ...
- [笔记]Laravel TDD 胡乱记录
TDD: 测试驱动开发(Test-Driven Development),TDD的原理是在开发功能代码之前,先编写单元测试用例代码,测试代码确定需要编写什么产品代码. -- 载自TDD百度百科 参考 ...
- CF774L Bars
题意:给你一个二进制表示是否可以吃巧克力.一共有k个巧克力,第一天和最后一天必须吃.最小化每两次吃巧克力的最大间隔? 标程: #include<bits/stdc++.h> using n ...
- leetcode-第10周双周赛-5080-查找两颗二叉搜索树之和
题目描述: 自己的提交: class Solution: def twoSumBSTs(self, root1: TreeNode, root2: TreeNode, target: int) -&g ...
- dos中文乱码怎么办?
最简单的方法: 通过 chcp命令改变代码页,UTF-8的代码页为65001 即chcp 65001 chcp 65001 就是换成UTF-8代码页 chcp 936 可以换回默认的GBK chcp ...
- 树的直径+质因子——好题!cf1101D
/* 因为质因子很少 状态转移时用dp[u][i]表示结点u的第i个质因子所在的最大深度即可 等价于带限制的求直径 */ #include<bits/stdc++.h> #include& ...
- class.forname & classloader
From https://www.cnblogs.com/gaojing/archive/2012/03/15/2413638.html 传统的使用jdbc来访问数据库的流程为: Class.forN ...
- 设置IDEA自动提示补全代码,关于idea自动补全的详细设置。
在IDEA中,默认的代码自动提示不够智能,现在配置成更加智能的方式. File-Settings-Editor-General-Code Completion中 把最上面的大小写敏感度改成none,下 ...
- LightOJ-1259-Goldbach`s Conjecture-素数打表+判断素数对数
Goldbach's conjecture is one of the oldest unsolved problems in number theory and in all of mathemat ...
- import time 进度条动态输出26个字母
# 2018-08-06 19:42:51 import time # 调用时间模块 num = 97 # 字母a while num <= 115: # print(chr(num), end ...