发布时间:2024-10-27 10:01
本文对 promise.all 方法进行讲解 ,参考 阮一峰老师的es6
需要了解 promise 基础的小伙伴 可以看 我的另一篇文章
Promise 对象实现 Ajax
通过 promise 对象实现 Ajax (如下) ,后面 promise.all 会使用到
下面代码中,
getJSON
是对 XMLHttpRequest 对象的封装,用于发出一个获取数据的 HTTP 请求,并且返回一个Promise
对象。需要注意的是,在getJSON
内部,resolve
函数和reject
函数调用时,都带有参数。
const getJSON = function(url) {
const promise = new Promise(function(resolve, reject){
const handler = function() {
if (this.readyState !== 4) {
return;
}
if (this.status === 200) {
resolve(this.response);
} else {
reject(new Error(this.statusText));
}
};
const client = new XMLHttpRequest();
client.open("GET", url);
client.onreadystatechange = handler;
client.responseType = "text";
client.setRequestHeader("Accept", "application/json");
client.send();
});
return promise;
};
getJSON("https://jsonplaceholder.typicode.com/users").then(function(json) {
console.log('Contents: ' + json);
}, function(error) {
console.error('出错了', error);
})
这个数据接口 共有十条数据 ,全部请求成功
Promise.all()
方法用于将多个 Promise 实例,包装成一个新的 Promise 实例。
const p = Promise.all([p1, p2, p3]);
上面代码中,Promise.all()
方法接受一个数组作为参数,p1
、p2
、p3
都是 Promise 实例,如果不是,就会先调用 Promise.resolve
方法,将参数转为 Promise 实例,再进一步处理。另外,Promise.all()
方法的参数可以不是数组,但必须具有 Iterator 接口,且返回的每个成员都是 Promise 实例。
p
的状态由p1
、p2
、p3
决定,分成两种情况。
(1)只有 p1
、p2
、p3
的状态都变成 fulfilled
,p
的状态才会变成 fulfilled
,
此时p1
、p2
、p3
的返回值组成一个数组,传递给 p
的回调函数。
(2)只要 p1
、p2
、p3
之中有一个被 rejected
,p
的状态就变成 rejected
,
此时第一个被 reject
的实例的返回值,会传递给 p
的回调函数。
// 生成一个Promise对象的数组
const promises = [1, 3, 5, 7, 9].map(function (id) {
return getJSON('https://jsonplaceholder.typicode.com/users/' + id);
});
Promise.all(promises).then(function (posts) {
console.log("ok")
console.log('Contents: ' + posts);
}).catch(function(reason){
console.log('出错了',reason)
});
上面代码中,promises
是包含 5个 Promise 实例的数组,只有这 5 个实例的状态都变成fulfilled
,或者其中有一个变为 rejected
,才会调用 Promise.all
方法后面的回调函数。
上面的代码正常运行 ,打印 ok 以及 id 为 1 3 5 7 9 的数据
上面 5 个 Promise 实例的数组 只要有一个变为
rejected ,就会调用 promise.all 的 catch
接口 只有10个数据 ,我把一个 ID 改成 19 ,这个地址不存在 自然就报错 ,调用
promise.all 的 catch
const databasePromise = connectDatabase();
const booksPromise = databasePromise
.then(findAllBooks);
const userPromise = databasePromise
.then(getCurrentUser);
Promise.all([
booksPromise,
userPromise
])
.then(([books, user]) => pickTopRecommendations(books, user));
上面代码中,
booksPromise
和userPromise
是两个异步操作,只有等到它们的结果都返回了,才会触发
pickTopRecommendations
这个回调函数。
如果作为参数的 Promise 实例,自己定义了
catch
方法,那么它一旦被rejected
,并不会触发Promise.all()
的catch
方法。
const p1 = new Promise((resolve, reject) => {
resolve('hello');
})
.then(result => result)
.catch(e => e);
const p2 = new Promise((resolve, reject) => {
throw new Error('报错了');
})
.then(result => result)
.catch(e => e);
Promise.all([p1, p2])
.then(result => console.log(result))
.catch(e => console.log(e));
// ["hello", Error: 报错了]
上面代码中,
p1
会resolved
,p2
首先会rejected
,但是p2
有自己的catch
方法,该方法返回的是一个新的 Promise 实例,p2
指向的实际上是这个实例。该实例执行完catch
方法后,也会变成resolved
,导致Promise.all()
方法参数里面的两个实例都会resolved
,因此会调用then
方法指定的回调函数,而不会调用catch
方法指定的回调函数。
如果 p2
没有自己的 catch
方法,就会调用 Promise.all()
的 catch
方法。(如下)
const p1 = new Promise((resolve, reject) => {
resolve('hello');
})
.then(result => result);
const p2 = new Promise((resolve, reject) => {
throw new Error('报错了');
})
.then(result => result);
Promise.all([p1, p2])
.then(result => console.log(result))
.catch(e => console.log(e));
// Error: 报错了
文章如有错误,恳请大家提出问题,本人不胜感激 。 不懂的地方可以评论,我都会一一回复
文章对大家有帮助的话,希望大家能动手点赞鼓励,大家未来一起努力 长路漫漫,道阻且长
转载请注明出处:https://blog.csdn.net/qq_52855464/article/details/125376557?spm=1001.2014.3001.5501