Promise.prototype.then()
Promise 实例具有then方法,then方法是定义在原型对象Promise.prototype上的。它的作用是为 Promise 实例添加状态改变时的回调函数。
then方法返回的是一个新的Promise实例(注意,不是原来那个Promise实例)。因此可以采用链式写法,即then方法后面再调用另一个then方法。
简单的看一个实例:
getJSON("/post/1.json").then(
post => getJSON(post.commentURL)
).then(
comments => console.log("resolved: ", comments),
err => console.log("rejected: ", err)
);
上述代码中,第一个then方法指的是回调函数,返回另一个Promise对象。第二个then方法指的回调函数,会等待这个新的Promise对象发生变化。
Promise.prototype.catch()
Promise.prototype.catch方法是.then(null, rejection)或.then(undefined, rejection)的别名,用于指定发生错误时的回调函数。
下面是一个例子:
const promise = new Promise(function(resolve, reject) {
throw new Error(‘test’);
});
promise.catch(function(error) {
console.log(error);
});
// Error: test
上面的代码中,Promise抛出了一个错误,就被catch方法指定的回调函数捕获。注意,上面的写法与下面两种写法是等价的。
// 写法一
const promise = new Promise(function(resolve, reject) {
try {
throw new Error(‘test’);
} catch(e) {
reject(e);
}
});
promise.catch(function(error) {
console.log(error);
});
// 写法二
const promise = new Promise(function(resolve, reject) {
reject(new Error(‘test’));
});
promise.catch(function(error) {
console.log(error);
});
下面看一个多层catch 捕获
someAsyncThing().then(function() {
return someOtherAsyncThing();
}).catch(function(error) {
console.log(‘oh no’, error);
// 下面一行会报错,因为y没有声明
y + 2;
}).catch(function(error) {
console.log(‘carry on’, error);
});
// oh no [ReferenceError: x is not defined]
// carry on [ReferenceError: y is not defined]
上面的代码,第二个catch方法用来捕获前一个catch方法抛出的错误
Promise.prototype.finally()
finally 方法总是会返回原来的值
// resolve 的值是 undefined
Promise.resolve(2).then(() => {}, () => {})
// resolve 的值是 2
Promise.resolve(2).finally(() => {})
// reject 的值是 undefined
Promise.reject(3).then(() => {}, () => {})
// reject 的值是 3
Promise.reject(3).finally(() => {})
Promise.all()
例如:
function connectDatabase() {
return new Promise(resolve => {
console.log(‘开始’)
resolve()
})
}
function findAllBooks() {
return new Promise(resolve => {
console.log('执行第一步')
resolve('book数据')
})
}
function getCurrentUser() {
return new Promise(resolve => {
console.log('第一步完成执行第二部')
resolve('user数据')
})
}
const databasePromise = connectDatabase();
const booksPromise = databasePromise
.then(findAllBooks);
const userPromise = databasePromise
.then(getCurrentUser);
// .all 触发所有的primise ; 传入的数组
Promise.all([
booksPromise,
userPromise
])
// 所有promise 异步完成的处理
// 大的promise 对象中与几个小的promise .then()的回调函数中;形参也要一一对应
.then(([books, user]) => pickTopRecommendations(books, user));
function pickTopRecommendations(books,user){
console.log(books)
console.log(user)
}
输出结果:
在这里插入图片描述
Promise.race()
Promise.race 方法同样是将多个Promise实例,包装成一个新的Promise实例。
例如:
var p1 = new Promise(resolve => console.log('p1'))
var p2 = new Promise(resolve => console.log('p2'))
var p3 = new Promise(resolve => console.log('p3'))
const p = Promise.race([p1, p2, p3]);
1
2
3
4
上面代码中,只要p1、p2、p3之中有一个实例率先改变状态,p的状态就跟着改变。那个率先改变的 Promise 实例的返回值,就传递给p的回调函数。
简单的写一个 加载图片的 Promise:
const preloadImage = function (path) {
return new Promise(function (resolve, reject) {
const image = new Image();
image.onload = resolve;
image.onerror = reject;
image.src = path;
});
};