一、Promise 的用途
Promise 是一个对象,它代表了一个异步操作的最终完成或者失败。本质上 Promise 是一个函数返回的对象,我们可以在它上面绑定回调函数,这样我们就不需要在一开始把回调函数作为参数传入这个函数了。
1、规范回调的名字或顺序
2、拒绝回调地狱,让代码可读性更强
3、更方便地捕获错误
二、如何创建一个 new Promise
return new Promise ((resolve,reject)=>{})
三、如何使用 Promise.prototype.then
then() 方法接受两个函数,成功的时候执行第一个函数,失败的时候执行第二个函数
const promise1 = new Promise((resolve, reject) => {
resolve('Success!');
});
promise1.then((value) => {
console.log(value);
});
// Success!
四、如何使用 Promise.all
- 当我们需要获得多个数据才进行下一步时使用Promise.all
Promise.all需要传入一个数组,数组中的元素都是Promise对象,当这些对象都执行成功,执行then中的第一个函数(成功函数),失败时只能获得第一个失败Promise的错误数据
Promise.all是大家一起到终点,一个失败全都失败
const promise1 = Promise.resolve(3);
const promise2 = 42;
const promise3 = new Promise((resolve, reject) => {
setTimeout(resolve, 100, 'foo');
});
Promise.all([promise1, promise2, promise3]).then((values) => {
console.log(values);
});
// [3, 42, "foo"]
五、如何使用 Promise.race
Promise.race()返回一个 Promise,它将与第一个传递的 promise 相同的完成方式被完成。它可以是完成( resolves),也可以是失败(rejects),这要取决于第一个完成的是哪一个。- 如果传的迭代是空的,则返回的 promise 将永远等待。
- 如果迭代包含一个或多个非承诺值和/或已解决/拒绝的承诺,则 Promise.race 将解析为迭代中找到的第一个值。
const promise1 = new Promise((resolve, reject) => {
setTimeout(resolve, 500, 'one');
});
const promise2 = new Promise((resolve, reject) => {
setTimeout(resolve, 100, 'two');
});
Promise.race([promise1, promise2]).then((value) => {
console.log(value);
// 哪个结果能更快获得取哪个
});
// "two"
手写一个Promise.all
Promise.prototype.myAll
Promise.myAll = function(list){
const results = []
let count = 0
return new Promise((resolve,reject) =>{
list.map((item, index)=> {
item.then(result=>{
results[index] = result
count += 1
if (count >= list.length) { resolve(results)}
}, reason => reject(reason) )
})
})
}
要点:
- 要在 Promise 上写而不是在原型上写
- 用数组来记录结果
- 只要有一个 reject 就整体 reject
六、如何使用 Promise.catch
catch() 方法返回一个Promise,并且处理拒绝的情况,主要用于捕捉错误。它的行为与调用Promise.prototype.then(undefined, onRejected) 相同
// 抛出一个错误,大多数时候将调用catch方法
var p1 = new Promise(function(resolve, reject) {
throw 'Uh-oh!';
});
p1.catch(function(e) {
console.log(e); // "Uh-oh!"
});
// 在异步函数中抛出的错误不会被catch捕获到
var p2 = new Promise(function(resolve, reject) {
setTimeout(function() {
throw 'Uncaught Exception!';
}, 1000);
});
p2.catch(function(e) {
console.log(e); // 不会执行
});
// 在resolve()后面抛出的错误会被忽略
var p3 = new Promise(function(resolve, reject) {
resolve();
throw 'Silenced Exception!';
});
p3.catch(function(e) {
console.log(e); // 不会执行
});
七、如何使用 Promise.finally
finally() 方法返回一个Promise。在promise结束时,无论结果是完成或者是拒绝,都会执行指定的回调函数。这为在Promise是否成功完成后都需要执行的代码提供了一种方式。
这避免了同样的语句需要在then()和catch()中各写一次的情况。
let isLoading = true;
fetch(myRequest).then(function(response) {
var contentType = response.headers.get("content-type");
if(contentType && contentType.includes("application/json")) {
return response.json();
}
throw new TypeError("Oops, we haven't got JSON!");
})
.then(function(json) { /* process your JSON further */ })
.catch(function(error) { console.log(error); })
.finally(function() { isLoading = false; });