- 一个
Promise
对象有三种状态:pending
,fufilled
,rejected
。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。 -
Promise
新建后就会立即执行。相当于同步,当所有的同步代码执行完,才会用then
方法调用异步的回调函数。 -
Promise
构造函数接受一个函数作为参数,该函数的两个参数分别是resolve
和reject
。它们是两个函数,由 JavaScript 引擎提供,不用自己部署。 -
Promise
实例生成以后,可以用then
方法分别指定resolved
状态和rejected
状态的回调函数。 -
resolve
的参数会传递给then
里的第一个回调函数,reject
的参数会传递给then
里的第二个回调函数。
Promise 链值传递和状态关联:
-
then
方法返回的是一个新的Promise
实例。 -
Promise.prototype.catch
方法是.then(null, rejection)
的别名。 -
fufilled
,rejected
的返回值类型:非 Promise 和 Promise 。
非 Promise
var p1 = new Promise(function (resolve, reject) {
reject(new Error('fail'))
});
var p2 = p1.then(value => value,err => err);
p2.then(value => {
console.log('this is p2.then');
console.log(value)
});
<···输出结果:
VM282:7 this is p2.then
VM282:8 Error: fail
at <anonymous>:2:10
at new Promise (<anonymous>)
at <anonymous>:1:11
Promise {<resolved>: undefined}
不管 p1
的结果是 resolved
还是 rejected
,p2
的结果都是 resolved
,这里很明显 p1
的结果是 rejected
,在 p2
的 resolved
中输出了 Error: fail。
Promise,即一个异步操作的结果是返回另一个异步操作:
const p1 = new Promise(function (resolve, reject) {
setTimeout(() => reject(new Error('fail')), 3000)
})
const p2 = new Promise(function (resolve, reject) {
setTimeout(() => {
console.log('in p2 Promise');
return resolve(p1);
}, 1000)
})
p2
.then(result => console.log(result))
.catch(error => console.log(error))
<···输出结果:
Promise {<pending>}
<···1秒后:
in p2 Promise
<···3秒后:
Error: fail
at setTimeout (<anonymous>:2:27)
这时 p1
的状态就会传递给 p2
,如果 p1
的状态是 pending
,那么 p2
的回调函数就会等待 p1
的状态改变;如果 p1
的状态已经是 resolved
或者 rejected
,那么 p2
的回调函数将会立刻执行。
Promise.all
Promise.all
方法用于将多个 Promise
实例,包装成一个新的 Promise
实例,Promise.all
方法接受一个数组(具有 Iterator
接口即可)作为参数,数组中的每一项都是一个 Promise
实例,如果不是,会调用 Promise.resolve
方法将参数转为 Promise
实例(Promise.race
的参数同理)。
const p = Promise.all([p3, p1, p2]);
p
的状态由 all
里的参数的状态决定,分成两种情况。
(1)只有 p1
、p2
、p3
的状态都变成 fulfilled
,p
的状态才会变成 fulfilled
,此时 p1
、p2
、p3
的返回值组成一个数组,传递给 p
的回调函数。
(2)只要 p1
、p2
、p3
之中有一个被 rejected
,p
的状态就变成 rejected
,此时第一个被 reject
的实例的返回值,会传递给p
的回调函数。
var p1 = new Promise((resolve, reject) => {
setTimeout(() => {
reject(new Error('err p1'))
}, 2000)
});
var p2 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('p2 p2 ')
}, 1000)
});
var p3 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('p3 p3 p3')
}, 3000)
});
var p = Promise.all([p3, p1, p2]);
p.then(res => console.log(res))
.catch(result => console.log(result));
<···运行结果:
Promise {<pending>}
<···3秒后:
VM124:23 Error: err p1
at setTimeout (<anonymous>:4:16)
var p1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('p1')
}, 2000)
});
var p2 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('p2 p2 ')
}, 1000)
});
var p3 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('p3 p3 p3')
}, 3000)
});
var p = Promise.all([p3, p1, p2]);
p.then(res => console.log(res))
.catch(result => console.log(result));
<···运行结果:
Promise {<pending>}
<···3秒后:
VM130:22 (3) ["p3 p3 p3", "p1", "p2 p2 "]
Promise.race
Promise.race
方法同样是将多个 Promise
实例,包装成一个新的 Promise
实例,只要 p1
、p2
、p3
之中有一个实例率先改变状态,p
的状态就跟着改变。那个率先改变的 Promise
实例的返回值,就传递给 p
的回调函数。
var p1 = new Promise((resolve, reject) => {
setTimeout(() => {
reject(new Error('err p1'))
}, 5000)
});
var p2 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('p2 p2 ')
}, 1000)
});
var p3 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('p3 p3 p3')
}, 1000)
});
var p = Promise.race([p3, p1, p2]);
p.then(res => console.log(res))
.catch(result => console.log(result));
<···运行结果:
Promise {<pending>}
<···1秒后:
VM258:22 p2 p2
var p1 = new Promise((resolve, reject) => {
setTimeout(() => {
reject(new Error('err p1'))
}, 1000)
});
var p2 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('p2 p2 ')
}, 1000)
});
var p3 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('p3 p3 p3')
}, 1000)
});
var p = Promise.race([p3, p1, p2]);
p.then(res => console.log(res))
.catch(result => console.log(result));
<···运行结果:
Promise {<pending>}
<···1秒后:
VM260:23 Error: err p1
at setTimeout (<anonymous>:4:16)
以上两段代码主要想强调,Promise.race
的参数中有一个 Promise
的状态率先改变,then
就会进行处理,不论这个状态是fufilled
还是 rejected
, 都会去 resolve
。
网友评论