JS 中的 Promise

Promise 是异步编程的解决方案,它能够很方便的处理异步事件。一个 Promise 实例包含一个异步操做,这项异步操做只有三种状态,pending 初始状态,既不是成功,也不是失败状态,Resolved 成功完成,Rejected 异步操做失败。javascript

Promise 的状态不受外界影响并且一旦状态改变,就不会再改变。java

建立 Promise

要建立 Promise 实例要用到 Promise 类,它接受一个函数做为参数,函数接受两个参数,这两个参数也是函数,一个是当异步成功执行时须要调用的函数,一个是失败时调用的函数。编程

建立 Promise 实例的参数函数,将会当即执行。数组

function getData(url) {
    return new Promise((resolve, reject) => {
        const xhr = new XMLHttpRequest();
        xhr.open("GET", url);
        xhr.onload = () => resolve(xhr.responseText); 
        // 将状态变为 Resolved 并传入获取到的数据
        xhr.onerror = () => reject(xhr.statusText);
        // 将状态变为 Rejected 并传入错误信息
        xhr.send();
    })
}

//调用 getData 将返回一个 Promise 实例
复制代码

Promise 的原型方法

Promise 一共有三个原型方法,then, catchfinallypromise

then

then 方法接受两个函数参数,一个是成功时候执行,一个是失败时执行。异步

并且then方法将会返回一个新的 Promise 实例,这就表明能够进行链式操做。异步编程

当即调用resolvePromise,它then方法的参数函数会放到本次事件循环末尾。函数

let p1 = getData('http://www.a.cn')

let onFulfilled = data => console.log(data)
let onRejected = err => console.log(err)

p1.then(onFulfilled, onRejected)

// 当成功时将会调用第一个回调函数,并把 resolve 传入的参数再所有传入 onFulfilled 中

// 当成功时将会调用第二个回调函数,并把 resolve 传入的参数再所有传入 onRejected 中

let p2 = getData('http://www.a.cn')

p2.then(url => getData(url))
  .then(data => console.log(data)) // 链式操做
  
// ------------------

let p = new Promise(resolve => {
    console.log(1)
    resolve(3)
})

console.log(2)

setTimeout(() => console.log(4))
p.then(num => console.log(num))
// 打印顺序是 1 2 3 4

复制代码

catch

catch 方法接受一个函数参数onRejectedcatch其实就是then的第二个参数。post

catch方法通常放在最后面,前面then方法,将会冒泡到它这里。ui

catch 返回的仍是一个 Promise 对象。不过catch捕获不了后面的then方法抛出的错误固然catch方法中也能够抛出错误。

let p3 = getData('http://a.com')

p3.then(data => console.log(data))
  .then(() => throw new Error('error')) // 抛出错误
  .then(() => console.log(1))
  .catch(err => console.log(err))
 
// catch 将会捕获上面的错误,并且第三个 then 方法会被跳过
复制代码

Promise 中未捕获的错误不会终止脚本执行而是打印一个未捕获 promise 错误提示。

finally

finally 方法接受一个函数参数onFinally。它无论 Promise 对象最后状态如何,都会执行的操做。finally方法的回调函数不接受任何参数。

它返回一个设置了 finally 回调函数的Promise对象。

Promise.prototype.finally = function (callback) {
  let P = this.constructor;
  return this.then(
    value => P.resolve(callback()).then(() => value),
    reason => P.resolve(callback()).then(() => { throw reason })
  );
};

// finally 至关于返回一个已经带两个参数的 then 方法
复制代码

Promise 方法

Promise 一共有 4 个静态方法。分别是all, race, resolvereject

resolve

resolve 接受一个参数,返回一个状态由给定value决定的Promise对象。

若是参数是 Promise 对象则直接返回。

若是参数是thenable(即,带有then方法的对象),then 方法会做为Promise的参数,当即执行。

若是是其余值返回一个新的 Promise 对象,状态为resolved,该value传递给对应的then方法。

Promise.resolve(1).then(num => {
    console.log(num)
});
复制代码

reject

reject 方法接受一个参数,返回一个状态为失败的Promise对象,并将给定的失败信息传递给对应的处理方法。

Promise.reject('error');
// 等同于
new Promise((resolve, reject) => reject('error'))
复制代码

all

all 方法接受具备 iterable 接口 参数。

这个方法返回一个新的promise对象,该promise对象在iterable参数对象里全部的promise对象都成功的时候才会触发成功,一旦有任何一个iterable里面的promise对象失败则当即触发该promise对象的失败。

这个新的promise对象在触发成功状态之后,会把一个包含iterable里全部promise返回值的数组做为成功回调的返回值,顺序跟iterable的顺序保持一致

若是这个新的promise对象触发了失败状态,它会把iterable里第一个触发失败的promise对象的错误信息做为它的失败错误信息。

参数中的每一个项目都是一个 Promise 对象,若是不是则用 resolve 方法转换成 Promise 对象。

race

race 方法和 all 方法同样,可是当iterable参数里的任意一个子 Promise 被成功或失败后,返回的 Promise 对象的状态就变成这个子 Promise 对象的状态,它的值或错误信息也会传递给返回 Promise 对象的回调函数。

Promise 的属性

Promise 一共有两个属性,lengthprototype

length属性,其值老是为 1 (构造器参数的数目)。

相关文章
相关标签/搜索