2019-12-17 | Promise |
---|
const promise = new Promise(function(resolve, reject) {
// ... some code
if (/* 异步操作成功 */){
resolve(value);
} else {
reject(error);
}
});
resolve() 把pending状态变为resolved状态,reject() 把pending状态变为rejected状态
实例:封装异步加载图片
function loadImageAsync(url) {
return new Promise(function(resolve, reject) {
const image = new Image();
image.onload = function() {
resolve(image);
};
image.onerror = function() {
reject(new Error('Could not load image at ' + url));
};
image.src = url;
});
}
resolve()和reject()函数中的参数会作为回调函数的参数来进行使用
new Promise((resolve, reject) => {
resolve(1);
console.log(2);
}).then(r => {
console.log(r);
});
// 2
// 1
注意:resolve()和reject()并不会终止函数的执行,所以最好在resolve()或reject()前面加上return
then方法返回的是一个新的Promise实例(注意,不是原来那个Promise实例)。因此可以采用链式写法
getJSON("/posts.json").then(function(json) {
return json.post;
}).then(function(post) {
// ...
});
promise.then(function(value) {
// success
}, function(error) {
// failure
});
错误会被回调的err函数捕获
2.catch写法
const promise = new Promise(function(resolve, reject) {
throw new Error('test');
});
promise.catch(function(error) {
console.log(error);
});
注意:如果在resolve()后面再抛出错误不会被catch捕获,因为这时候pending的状态已经被改变,不会再次改变
3.Promise的错误具有冒泡性质,就是错误一直向后传递,直到被捕获为止
getJSON('/post/1.json').then(function(post) {
return getJSON(post.commentURL);
}).then(function(comments) {
// some code
}).catch(function(error) {
// 处理前面三个Promise产生的错误
});
4.和传统的try…catch不同,如果Promise没有使用catch,Promise抛出的错误不会有任何反应,也不会阻挡程序的执行
5.catch方法返回的还是一个Promise对象,因此后面还可以调用then方法
Promise.resolve()
.catch(function(error) {
console.log('oh no', error);
})
.then(function() {
console.log('carry on');
});
//carry on
因为没有抛出错误,所以直接执行了后面的then方法,换成reject()抛出错误会执行catch和then方法
6.catch方法之中,还能再抛出错误。抛出的错误将会被下一个catch接收
不管Promise最后的状态如何,都会执行finally方法,并且不接受任何参数
将多个Promise实例包装成一个Promise实例,Promise.all的参数可以不是数组,但是必须要有Iterator接口
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: 报错了]
//如果p2没有catch方法,则会被Promise.all()捕获
const p = Promise.race([p1, p2, p3]);
p1,p2,p3三个Promise实例中哪个先返回resolve,则race().then的参数就是先返回的那个参数,只有全部reject()后才会触发rece().catch()方法
接收一个可遍历对象作为参数,之后所有的可便利对象都返回结果时候才会执行then
const resolved = Promise.resolve(42);
const rejected = Promise.reject(-1);
const allSettledPromise = Promise.allSettled([resolved, rejected]);
allSettledPromise.then(function (results) {
console.log(results);
});
// [
// { status: 'fulfilled', value: 42 },
// { status: 'rejected', reason: -1 }
// ]
作用:将现有的对象转换为Promise对象
Promise.resolve('foo')
// 等价于
new Promise(resolve => resolve('foo'))
参数分为四种情况:
let thenable = {
then: function(resolve, reject) {
resolve(42);
}
};
let p1 = Promise.resolve(thenable);
p1.then(function(value) {
console.log(value); // 42
});
3.参数不是具有then方法的对象,或根本不是对象,则Promise.resolve()返回的是一个新的Promise对象,状态是resolve()
const p = Promise.resolve('Hello');
p.then(function (s){
console.log(s)
});
// Hello
4.不带有任何参数,直接返回一个resolved状态的 Promise 对象。
const p = Promise.resolve();
p.then(function () {
// ...
});
Promise.reject()返回的也是一个Promises实例,该实例的状态是rejected()
const p = Promise.reject('出错了');
// 等同于
const p = new Promise((resolve, reject) => reject('出错了'))
p.then(null, function (s) {
console.log(s)
});
// 出错了
Promise.reject()的参数和resolve方法不同,会原封不动的被catch接收
const thenable = {
then(resolve, reject) {
reject('出错了');
}
};
Promise.reject(thenable)
.catch(e => {
console.log(e === thenable)
})
// true
参考文献
阮一峰官网(ES6 Promise对象)