ES6学习——生成器(Generators):生成器+Promises

73 篇文章 23 订阅

Promise是个异步执行的过程,我们要想把多个Promise顺序执行,只能不断的利用then方法继续去执行下面的Promise,例如:

step1().then(step2,step2Failed).then(function(msg) {
    return Promise.all( [
        step3a( msg ),
        step3b( msg ),
        step3c( msg )
    ] )
})
.then(step4);

上面这段代码的逻辑就是step1完了,在执行step2或者step2Failed,然后在step3的三个步骤,最后step4,是个顺序执行的过程,但是Promise的语法中却不能清楚的反应出这样一个顺序,不太利于人眼阅读。

而生成器有一个特点就是可以中断-恢复函数的执行,利用这点可以yield一个Promise,接着在Promise状态fulfilled的时候,继续执行。可以把异步过程调用顺序化,看下面的代码:

		function* main() {
			var ret = yield step1();
			try {
				ret = yield step2( ret );
			}
			catch (err) {
				ret = yield step2Failed( err );
			}

			ret = yield Promise.all( [
				step3a(ret),
				step3b(ret),
				step3c(ret)] 
			);

			yield step4( ret );

			return done();
		}

要想让上面的生成器执行起来,当然可以自己一个next一个next的去调用,但这样很麻烦,可以写个通用的函数:

function run(gen) {
			var args = [].slice.call( arguments, 1), it;
			it = gen.apply( this, args );
			
			return Promise.resolve().then( function handleNext(value){
						console.log("==>",value);
						var next = it.next(value);
						return (function handleResult(next){
							if (next.done) {
								return next.value;
							}
							else {//这面递归调用
								return Promise.resolve(next.value).then(handleNext,function handleErr(err) {
									return Promise.resolve(it.throw( err )).then( handleResult );
								});
							}
					})( next );
			});
		}

具体过程函数的代码:

		function step1(){
			return Promise.resolve("step 1");
		}

		function step2(){
			return Promise.resolve("step 2");
			//return Promise.reject("step 2 ERROR!");
		}

		function step2Failed(err){
			console.error(err);
			return Promise.resolve("step2 failed!But We can continue.");
		}

		function step3a(){
			return Promise.resolve("step 3a");
		}

		function step3b(){
			return Promise.resolve("step 3b");
		}

		function step3c(){
			return Promise.resolve("step 3c");
		}

		function step4(){
			return new Promise(function(resolve,reject){
				setTimeout(function(){
					resolve("step 4");
				},1000);
			});
		}

		function done(){
			return Promise.resolve("DONE!!");
		}

调用run:

		run( main )
			.then(
			function fulfilled(result){
				console.log("finally:",result);
			},
			function rejected(reason){
				
			}
		);

最后结果:


如果在step2中用Promise.reject,可以验证step2failed过程:


是不是觉得上面的过程有点复杂,不过不要担心,在将来的ES7中会有一个async的关键字,直接加在函数前面,就能实现上面的过程。在介绍ES7的时候在解释。这里只需要记住生成器和Promise可以叠加使用,把异步过程顺序化就好了。


*以上全部代码在Chrome 47下通过测试

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值