Es6系列之深入generator2
利用generator来调用异步主要是为了解决异常调用嵌套的问题,下面先模拟一个嵌套调用的异步过程.
functin request(delay, callback){ setTimeout(function(){ callback({ name: feenan }, +delay); request(1000, function(msg){ console.log(msg); request(2000, function(msg){ console.log(msg);
然后我们来看看怎么用generator来同步处理这里请求,首先我们来定义生成器函数.
function* main(){ var result = yield request(1000); console.log(result); var result1 = yield request(2000); console.log(result); var it = main();
此时我们需要改进下request函数.
functin request(delay){ setTimeout(function(){ it.next({ name: feenan }, +delay);
注意上面的异步函数里增加了it.next,这样就能保证回调的值能传入main函数里去.因为next函数的参数是上一次yield表达式的值,第一次给next传参默认会忽略.
上面的方案虽然实现了异步方法的扁平化处理,但是有些缺点
异步方法深度依赖生成器实例,倒致不能重用 不能处理多个异步同时调用的情况来看看第二种方案是怎么解决这种问题的?
第二种方案promise虽然上面的方案可以实现异步调用的扁平化处理,但是仍然存在问题,下面我们来用Promise来实现一个更好的扁平化方案
Promise是es6提供的原生支持promise规范的类,提供有then,all,catch方法.我们先来改装下request方法
function request(id, delay){ return new Promise(function(resolve, reject){ setTimeout(function(){ if(id == 1) reject(new Error(new Error!)); resolve({ name: feenan, id: id }, +delay);
Promise通过new一个实例,传入待执行的异步方法,内部利用resolve,reject来导出成功和失败的信息.可以看出这个方法跟generator是完全没关系的,已经解藕了,而且也可以重用在别的类库里,然后我们再来定义我们的生成器函数.
function* main(){ try{ var result = yield request(1, 1000); if(result.name == feenan){ var result1 = yield request(2, 2000); return done!; }catch(err){ console.log(err);
此处的try...catch是用来捕获里面异步方法的异常的,通过throw方法,这个等会儿会讲到.
也许大家会看到,上面的main方法的yield会返回一个promise对象,但是result应该会接收到异步回调结果的,这里我们应该怎么处理呢?对,我们还需要定义一个运行生成器函数的函数.
function runGenerator(g){ return new Promise(function(resolve, reject){ var it = g(), ret; (function iterate(val){ ret = it.next(val); if(!ret.done){ // 检查是否是promise对象 if(then in ret.value){ ret.value.then(iterate).catch(function(err){ it.throw(err); }else{ setTimeout(function(){ iterate(ret.value); }, 0) }else{ resolve(ret); })();
代码看起来有点复杂,我一一来解释.
首先函数本身返回一个promise对象用来处理生成器函数返回值,内部定义了一个iterate立即执行函数,runGenerator内部会先生成一个迭代器名为it,参数即是生成器函数,然后iterate会先调用it.next传递参数,默认第一次参数会忽略,然后检查it.next的返回值,这个返回值属性格式默认为{value: , done: },value为yield后表达式的返回值,done代表迭代是否完毕,因为yield后面返回的是一个promise对象,所以检查ret.value是否是一个promise对象,是的话则调用then方法传递当前iterate本身,这就是运行函数的奥妙所在,因为此时会把异步回调的结果传递给下一次的it.next,这样main函数里的result就能接收到异步回调的结果了,然后就是不断重复上面的步骤直到执行完毕,利用resolve向外抛出生成器函数的返回值,我们来看看运行的样子
runGenerator(main).then(msg){ console.log(msg); // = done!
另外我们还可以利用promise.all方法达到异步同时调用多个方法的功能,此处只需要定义一个多个异步调用方法,promise.all会调用多个promise对象最终只返回一个promise对象
// 包装多个异常请求成功之后返回一个新的promise // 利用Promise.all类方法 function requestAll(){ var promises = [1000, 2000, 3000].map(function(v, k){ return new Promise(function(resolve, reject){ setTimeout(function(){ resolve({ name: feenan, id: v }, v); return Promise.all(promises);
然后我们修改main函数里的request即可
// var result = yield request(1, 1000); var result = yield requestAll();
此处需要注意下,上面的result是一个数组,里面每项为单个promise对象的返回值
可以看到利用promise+generator可以完美的原生实现异步调用扁平化,这对复杂业务逻辑的实现是相当好的.
下面我再说说es7里对于异步调用方法的更进一步的完美支持,而且代码量更少
第三种方案asynces7里提供了async语法来定义异步函数,配合await关键字轻易就能实现上面的功能
function request(id, delay){ return new Promise(function(resolve, reject){ setTimeout(function(){ if(id == 1) reject(new Error(new Error!)); resolve({ name: feenan, id: id }, +delay);
await告诉引擎需要等后面的异步执行完成之后才能执行下面的语句,这是原生支持的,不需要像上面那样定义运行函数来一步一步执行.
await后面必须是一个promise对象实例,所以这里也的用上promise特性.
不过async语法成为标准之路还很遥远,庆幸的是traceur支持这个语法.
最后我觉的还是promise和generator是完美解决异步调用的方案,以上所有实例都可以通过traceur命令来运行.
浅析-ES6 后端项目搭建完毕,接下来就是前端页面了。不过在这之前需要一些准备工作。我们需要学习ES6的语法标准。
浅谈一下ES6的提升 es6的提升 在es6之前,我们定义定义变量的时候,只能使用var关键字来定变量,这样有一个问题,var定义的变量会成为全局变量。
一篇文章带你学会整个ES6 ES 全称 EcmaScript,是脚本语言的 规范 ,而平时经常编写的 JavaScript ,是 EcmsScript 的 一种实现 ,所以 ES 新特性其实是指 JavaScript 的新特性 。
3DES数据加密算法 3DES数据加密算法是一种可逆的对称加密算法,也称三重数据加密算法(英语:Triple Data Encryption Algorithm,缩写为TDEA,Triple DEA),或称3DES(Triple DES),它是一种为了替代原先DES而建立的数据加密标准。
相关文章
- ES6字符串包含方法
- [ES6] Class Inherit
- [AngularJS + Webpack] ES6 with BabelJS
- [React] React components in ES6 classes
- [ES6] 22. Const
- js es6系列——map函数
- js es6深入应用系列(Generator)
- [ES6] Array.find()
- Es6系列之module and class
- Es6系列之深入generator之异常处理与相互调用
- atitit 新特性与趋势管理的艺术 v2 s52.docx 1. lang语言系列 java node.js php 2 1.1. Atitit js es5 es6新特性 attilax总结
- ES6, Angular,React和ABAP中的String Template(字符串模板)
- Es6箭头函数
- es6 语法 (symbol)
- ES6新特性
- 前端系列-ES6系列
- JavaScript前端经典面试题之ES6面试题汇总es6
- 00-ES6补充