Promise结合reduce构建顺序执行队列

    Promise是一个解决函数异步执行的对象,有了这个对象,我们可以构造异步执行的操作。Promise对象可以通过链式调用的方式进行异步操作,语法如下:

    

    如下代码,是一个简单的异步方法。

new Promise((resolve,reject)=>{console.log("promise-> hello,world.this is promise. "+new Date());setTimeout(()=>{resolve("hello,world.this is promise. "+new Date());},1000);
}).then((value)=>{console.log("then   -> "+value);
});

    运行这段代码,得到结果如下所示:

     

    通过Proimse我们很好的构建了一个异步操作,then中的函数始终都会在resolve()执行之后才开始执行。resolve()可以携带参数,这个参数到了then里面,就可以通过回调函数中的参数获取了,如题所示的value值,就是通过resolve(args)传递过来的。 

    另外,这里还有一个reject函数,就是当Promise内部执行出现异常,我们才会调用。这时候,一般then是不会执行的,这里如果要在reject后,继续执行then中的内容,我们需要在then中增加一个reject的函数处理。

new Promise((resolve,reject)=>{console.log("promise-> hello,world.this is promise. "+new Date());setTimeout(()=>{reject("hello,world.this is promise. "+new Date());},1000);
}).then((value)=>{console.log("resolve-> "+value);
},(value)=>{console.log("reject -> "+value);
});

    执行结果如下:

     

    一般情况下,为了简单,Promise只用来做异步处理,我们都不处理reject的情况,所以Promise写起来会很简单。比如:

new Promise(resolve=>{console.log("promise-> hello,world.this is promise. "+new Date());setTimeout(()=>{resolve("hello,world.this is promise. "+new Date());},1000);
}).then(value=>{console.log("resolve-> "+value);
});

    以上示例,从直观上感受到了Promise的强大,我们再也不用通过函数嵌套回调的方式来做异步操作了。如下所示的异步回调方法,一层套一层:

setTimeout(function(){//todosetTimeout(function(){//todosetTimeout(function(){//todo},1000);},1000);
},1000);

    嵌套回调,容易造成callback hell,Promise的then中,可以继续返回新的Promise,这样,可以构建一个简单的异步回调。而且写法更直观,更易于理解:

new Promise(resolve=>{console.log("promise 1");setTimeout(()=>{resolve();},1000);
}).then(()=>{return new Promise(resolve=>{console.log("promise 2");setTimeout(()=>{resolve();},1000);});
}).then(()=>{return new Promise(resolve=>{console.log("promise 3");setTimeout(()=>{resolve();},1000);});
});

    Promise除了以上的用法,还可以有Promise.all().then()的用法,all()表示所有的操作均执行完成,再执行then()中的方法。而all()中的函数,不是顺序执行,而是同时执行。

const createPromise = (id) => new Promise(resolve=>setTimeout(()=>{console.log("promise->"+id+":"+new Date());resolve();},1000))
var tasks = [createPromise(1),createPromise(2),createPromise(3)];
console.log(tasks);
Promise.all(tasks).then(()=>console.log("all done."));

    运行结果:

     

    从运行结果看来,他们几乎是同一时刻,这种异步,虽然最终都会全部执行完成,再执行then()中的代码,但是all()中的函数并没有顺序执行。如果希望then()之前的函数都是顺序执行的,可以考虑通过reduce函数来实现。这里会比较难以理解。

const createPromise = (id) => () => new Promise(resolve=>setTimeout(()=>{console.log("promise->"+id+":"+new Date());resolve();},1000))
var tasks = [createPromise(1),createPromise(2),createPromise(3)];
console.log(tasks);
var doTask = tasks.reduce((prev,next)=>prev.then(()=>next()),Promise.resolve());
doTask.then(()=>console.log("all done."));

    这里需要注意的是,我们的createPromise函数,不再返回的是Promise对象,而是一个函数,函数里面再返回Promise对象。运行我们的代码,截图如下:

     

    可以看到,这里三个函数是按照顺序执行的,并没有同时执行,等到全部执行完成,最后执行then()中的方法。其实这种reduce写法,就回到了我们前面提到的Promise().then().then().then()的写法, 只不过使用reduce代码更简洁了,我们需要注意的是reduce()的数组是一个Function的数组,而不是Promise的数组。另外,reduce()方法的第二个参数,他是一个初始值,在这里就是Promise.resolve(),他表示一个动作已经执行完成,可以进行下一个动作了。


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部