在我们的异步调用时经常有这样一种场景:我们需要同时调用多个异步操作,但希望只有等所有的操作都完成后,我们才去执行响应操作——这就是 Promise.all 的作用。 Promise.all 方法可以接收多个 promise 作为参数,以数组的形式,当这些 promise 都成功执行完成后才调用回调函数。
Promise.all([promise1, promise2]).then(function(results) { // Both promises resolved }) .catch(function(error) { // One or more promises was rejected });
一个很好的能演示 Promise.all 用法的例子是,执行多个 AJAX 操作(通过 fetch) 调用:
var request1 = fetch('/users.json'); var request2 = fetch('/articles.json'); Promise.all([request1, request2]).then(function(results) { // Both promises done! });
我们还可将fetch和电池状态API混合一起执行,因为它们返回的都是 promise:
Promise.all([fetch('/users.json'), navigator.getBattery()]).then(function(results) { // Both promises done! });
一旦 promise 里调用了reject函数,也就是执行被拒绝了,没有能够正常完成,情况会有些复杂。一旦 promise 被拒绝,catch 方法会捕捉到首个被执行的reject函数:
var req1 = new Promise(function(resolve, reject) { // A mock async action using setTimeout setTimeout(function() { resolve('First!'); }, 4000); }); var req2 = new Promise(function(resolve, reject) { // A mock async action using setTimeout setTimeout(function() { reject('Second!'); }, 3000); }); Promise.all([req1, req2]).then(function(results) { console.log('Then: ', one); }).catch(function(err) { console.log('Catch: ', err); }); // From the console: // Catch: Second!
Promise.all 是非常重要的接口,将会在很多新诞生的 promise API中扮演重要的作用。
Promise.race
Promise.race 是一个有趣的函数——它不是等待所有的 promise 被resolve 或 reject,而是在所有的 promise 中只要有一个执行结束,它就会触发:
var req1 = new Promise(function(resolve, reject) { // A mock async action using setTimeout setTimeout(function() { resolve('First!'); }, 8000); }); var req2 = new Promise(function(resolve, reject) { // A mock async action using setTimeout setTimeout(function() { resolve('Second!'); }, 3000); }); Promise.race([req1, req2]).then(function(one) { console.log('Then: ', one); }).catch(function(one, two) { console.log('Catch: ', one); }); // From the console: // Then: Second!
一个有用的场景是,从多个镜像服务器下载资源,一旦有一个返回,其它的返回也就不用处理了。
学会使用 Promises
Promises在过去几年是一个非常火爆的话题,它甚至从JavaScript里抽离出来变成了一个语言架构。相信很快我们将见到有愈来愈多的JavaScript API将使用以promise为基础的模式。