Promise 是异步编程的一种解决方案。
Promise
对象两个特点:
对象的状态不受外界影响。Promise
对象代表一个异步操作,有三种状态:pending
(进行中)、fulfilled
(已成功)和rejected
(已失败)。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。
一旦状态改变,就不会再变。称为 resolved[已定型]。
从pending变为fulfilled 或者 从pending变为rejected
Promise
缺点:
无法取消 Promise ,一旦新建它就会立即执行,无法中途取消。
如果不设置回调函数,Promise 内部抛出的错误,不会反应到外部。
当处于 pending 状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)。
一、基础用法
//新建promise对象 两个参数resolve, reject
const promise = new Promise(function(resolve, reject) {
if (/* 异步操作成功 */){
resolve(value);
} else {
reject(error);
}
});
promise
.then( //promise的resolved回调函数
result => {console.log("resolved: ", result)}, //then的第一方法成功回调,
err => console.log("rejected: ", err) //then的第二个失败回调 (可选) 不推荐 更推荐在catch捕获错误
.catch(error => {···}) //promise的resolved回调函数
.finally(() => {···}); //在执行`then`或`catch`后,都会执行`finally`回调
二、Promise.prototype.then()
第一个参数是resolved
状态的回调函数,
第二个参数(可选)是rejected
状态的回调函数
getJSON("/post/1.json").then(
post => getJSON(post.commentURL)
).then(
comments => console.log("resolved: ", comments),
err => console.log("rejected: ", err)
);
第一个`then`方法指定的回调函数,返回的是另一个`Promise`对象。
第二个`then`方法指定的回调函数,就会等待这个新的`Promise`对象状态发生变化。如果变为`resolved`,就调用第一个回调函数,
如果状态变为`rejected`,就调用第二个回调函数。
三、Promise.prototype.catch()
Promise.prototype.catch() 是.then(null, rejection)或.then(undefined, rejection)的别名。
和then的二个参数一样用来指定reject的回调
。
但是比then的二个参数一个作用:在执行resolve的回调(也就是上面then中的第一个参数)时,如果抛出异常了(代码出错了),那么并不会报错卡死js,而是会进到这个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);
});
then的第二个函数与catch( )的区分
(1)Promise内部报错 则then的第二个函数和catch就近原则能捕获到
const promise = new Promise((resolve, rejected) => {
throw new Error('test');
});
//情况一:既有第二个函数也有catch时 就近原则
promise.then(res => {
}, err => {
console.log('我比较近我能捕获到',err);
}).catch(err1 => {
console.log(err1);
});
运行结果:我比较近我能捕获到,test
//情况二:只有第二个函数或只有catch 那就是它能捕获
(2) then
的第二个的函数捕获不了then中的第一个函数抛出的错误
,而后续的.catch
可以捕获。
Promise.resolve()
.then(function success (res) {
throw new Error('error')
}, function fail1 (e) {
console.error('fail1: ', e)~~~~
})
.catch(function fail2 (e) {
console.error('fail2: ', e)
})
运行结果:
fail2: Error: error
at success (...)
at ...
四、Promise.prototype.finally()
如服务器使用 Promise 处理请求,然后使用finally
方法关掉服务器
server.listen(port)
.then(result => {···})
.finally(server.stop);
五、Promise的一些方法
Promise.all() 全返回回来才回调操作
// 生成一个Promise对象的数组
const promises = [2, 3, 5, 7, 11, 13].map(function (id) {
return getJSON('/post/' + id + ".json");
});
Promise.all(promises).then(function (posts) {
}).catch(function(reason){
});
如果子promise没有报错了 但是子promise没有定义catch, 就会调用promise.all的catch。
Promise.race() 只要有一个回来就回调操作
// 有一个图片加载完就添加到页面
function loadImg(src){
return new Promise((resolve,reject)=>{
let img=document.createElement('img');
img.src=src;
img.onload=function(){
resolve(img);
}
img.onerror=function(err){
reject(err);
}
})
}
function showImgs(img){
let p=document.createElement('p');
p.appendChild(img);
document.body.appendChild(p)
}
Promise.race([
loadImg('http://www.baidu.com/1.png'),
loadImg('http://www.baidu.com/567751/2.png'),
loadImg('http://www.baidu.com/567751/3.png')
]).then(showImgs)
Promise.resolve( ) 转为Promise对象
(1)参数是一个 Promise 实例 原封不动地返回这个实例
(2)不带有任何参数 直接返回一个resolved
状态的 Promise 对象
(3)参数是一个thenable
对象(即具有then
方法的对象)
Promise.resolve方法会将这个对象转为 Promise 对象,然后就立即执行thenable对象的then方法。
//`thenable`对象指的是具有`then`方法的对象
let thenable = {
then: function(resolve, reject) {
resolve(42);
}
};
let p1 = Promise.resolve(thenable);
p1.then(function(value) {
console.log(value); // 42
});
(4)参数不是具有then
方法的对象,或根本就不是对象
如果参数是一个原始值,或者是一个不具有then
方法的对象,则Promise.resolve
方法返回一个新的 Promise 对象,状态为resolved
。
const p = Promise.resolve('Hello');
p.then(function (s){
console.log(s)
});
// Hello
Promise.reject( ) 转为Promise对象 且状态是rejected
和Promise.resolve方法一样,Promise.reject方法产生的Promise对象的状态是rejected的。
const p = Promise.reject('出错了');
// 等同于
const p = new Promise((resolve, reject) => reject('出错了'))
p.then(null, function (s) {
console.log(s)
});
// 出错了
mark一下 仅供参考 欢迎更正补充 Thanks
参考资料:
阮一峰:https://es6.ruanyifeng.com/?search=String.raw&x=0&y=0#docs/promise#Promise-all
关于promise的十道题目:https://juejin.im/post/5a0406...
性感的Promise,拥抱ta然后扒光ta:https://juejin.im/post/5ab20c...
通俗易懂的Promise:https://juejin.im/post/5afe6d...
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。