1、一个 Promise有以下几种状态:
pending: 初始状态,既不是成功,也不是失败状态。
fulfilled: 意味着操作成功完成。
rejected: 意味着操作失败。
2、
ES6 规定,
Promise
对象是一个构造函数,用来生成
Promise
实例。
有了
Promise
对象,就可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数。
Promise是一个构造函数,自己身上有all、reject、resolve这几个眼熟的方法,原型上有then、catch等同样很眼熟的方法。这么说用Promise new出来的对象肯定就有then、catch方法
// Promise 不论成功或失败都会调用 then
// catch() 只有当 promise 失败时才会调用
then
方法返回的是一个新的Promise
实例(注意,不是原来那个Promise
实例)。
一般来说,不要在
then
方法里面定义 Reject 状态的回调函数(即then
的第二个参数),总是使用catch
方法。
Promise 内部的错误不会影响到 Promise 外部的代码,通俗的说法就是“Promise 会吃掉错误”。
3、示例
Promise 新建后就会立即执行。
let
promise
=
new
Promise
(
function
(
resolve
,
reject
){
console
.
log
(
'Promise'
);
resolve
();
});
promise
.
then
(
function
(){
console
.
log
(
'resolved'
);
});
console
.
log
(
'Hi!'
);
//Promise Hi resolved
//用Promise对象实现的Ajax操作
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
.
oprn
(
"GET"
,
url
);
client
.
onreadystatechange
=
handler
;
client
.
responseType
=
"json"
;
client
.
setRequestHeader
(
"Accept"
,
"application/json"
);
client
.
send
();
})
return
promise
;
}
getJson
(
'/post.json'
).
then
(
function
(
json
){
console
.
log
(
'Contents:'
+
json
);
},
function
(
error
){
console
.
error
(
"出错了"
,
error
);
})
4、then方法的第一个参数是resolved状态的回调函数,第二个参数(可选)是rejected状态的回调函数。
Promise.prototype.catch方法是.then(null, rejection)的别名,用于指定发生错误时的回调函数。
建议第二种写法
// bad
promise
.then(function(data) {
// success
}, function(err) {
// error
});
// good
promise
.then(function(data) { //cb
// success
})
.catch(function(err) {
// error
});
5、跳过继续执行
//promise会吃掉错误
const
someAsyncThing
=
function
(){
return
new
Promise
(
function
(
resolve
,
reject
){
resolve
(
x
+
2
); //报错
});
}
someAsyncThing
().
then
(
function
(){
console
.
log
(
'every thing is great'
);
});
setTimeout
(()
=>
{
console
.
log
(
123
); //还是会输出123
},
2000
);
6、finally方法用于指定不管 Promise 对象最后状态如何,都会执行的操作。
finally方法的回调函数不接受任何参数,这意味着没有办法知道,前面的 Promise 状态到底是fulfilled还是rejected。这表明,finally方法里面的操作,应该是与状态无关的,不依赖于 Promise 的执行结果。
7. Promise.all()
const p = Promise.all([p1, p2, p3]);
Promise.all
方法用于将多个 Promise 实例,包装成一个新的 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
的回调函数。
const p = Promise.race([p1, p2, p3]);
Promise.race
方法同样是将多个 Promise 实例,包装成一个新的 Promise 实例。
上面代码中,只要
p1
、
p2
、
p3
之中有一个实例率先改变状态,
p
的状态就跟着改变。那个率先改变的 Promise 实例的返回值,就传递给
p
的回调函数。
9. Promise.resolve()
有时需要将现有对象转为 Promise 对象,
Promise.resolve
方法就起到这个作用。
Promise.resolve('foo')
// 等价于
new Promise(resolve => resolve('foo'))
10.Promise.reject()
const p = Promise.reject('出错了');
// 等同于
const p = new Promise((resolve, reject) => reject('出错了'))
p.then(null, function (s) {
console.log(s)
});
// 出错了
10. Promise出现的原因
Promise的出现主要是解决地狱回调的问题,比如你需要结果需要请求很多个接口,这些接口的参数需要另外那个的接口返回的数据作为依赖,这样就需要我们一层嵌套一层,但是有了Promise 我们就无需嵌套。
它最大的作用就是解决了异步回调函数层层嵌套的问题。
11.
每一个异步任务会立刻返回一个Promise对象。Promises对象有一个then方法,允许指定回调函数,在异步任务完成后调用。
12.
Promise对象的最终结果只有两种:
1 异步操作成功 Promise对象传回一个值,状态变为resolved
2 异步操作失败 Promise对象抛出一个错误,状态变为rejected
1 异步操作成功 Promise对象传回一个值,状态变为resolved
2 异步操作失败 Promise对象抛出一个错误,状态变为rejected
var foo = {
then: (resolve, reject) => resolve('foo')
};
var resolved = Promise.resolve(foo);
相当于
var resolved = new Promise((resolve, reject) => {
foo.then(resolve, reject)
});
resolved.then((str) =>
console.log(str);//foo
)