Promise

作者: McDu | 来源:发表于2018-03-16 10:59 被阅读5次
  • 一个 Promise 对象有三种状态:pending,fufilled,rejected。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。
  • Promise 新建后就会立即执行。相当于同步,当所有的同步代码执行完,才会用 then 方法调用异步的回调函数。
  • Promise 构造函数接受一个函数作为参数,该函数的两个参数分别是 resolvereject。它们是两个函数,由 JavaScript 引擎提供,不用自己部署。
  • Promise 实例生成以后,可以用 then 方法分别指定 resolved 状态和 rejected 状态的回调函数。
  • resolve 的参数会传递给 then 里的第一个回调函数, reject 的参数会传递给 then 里的第二个回调函数。

Promise 链值传递和状态关联:

  • then 方法返回的是一个新的 Promise 实例。
  • Promise.prototype.catch 方法是 .then(null, rejection) 的别名。
  • fufilled,rejected的返回值类型:非 PromisePromise

非 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

相关文章

网友评论

      本文标题:Promise

      本文链接:https://www.haomeiwen.com/subject/yhylqftx.html