Promise

2018-03-16  本文已影响5人  McDu

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 还是 rejectedp2 的结果都是 resolved,这里很明显 p1 的结果是 rejected,在 p2resolved 中输出了 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)只有 p1p2p3 的状态都变成 fulfilledp 的状态才会变成 fulfilled,此时 p1p2p3 的返回值组成一个数组,传递给 p 的回调函数。

(2)只要 p1p2p3 之中有一个被 rejectedp 的状态就变成 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 实例,只要 p1p2p3 之中有一个实例率先改变状态,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

上一篇 下一篇

猜你喜欢

热点阅读