Promise 是异步编程的解决方案,它能够很方便的处理异步事件。一个 Promise 实例包含一个异步操做,这项异步操做只有三种状态,pending
初始状态,既不是成功,也不是失败状态,Resolved
成功完成,Rejected
异步操做失败。javascript
Promise 的状态不受外界影响并且一旦状态改变,就不会再改变。java
要建立 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 一共有三个原型方法,then
, catch
和 finally
。promise
then
方法接受两个函数参数,一个是成功时候执行,一个是失败时执行。异步
并且then
方法将会返回一个新的 Promise 实例,这就表明能够进行链式操做。异步编程
当即调用resolve
的Promise
,它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
方法接受一个函数参数onRejected
,catch
其实就是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
方法接受一个函数参数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 一共有 4 个静态方法。分别是all
, race
, resolve
和 reject
。
resolve
接受一个参数,返回一个状态由给定value决定的Promise对象。
若是参数是 Promise 对象则直接返回。
若是参数是thenable(即,带有then方法的对象),then 方法会做为Promise
的参数,当即执行。
若是是其余值返回一个新的 Promise 对象,状态为resolved,该value传递给对应的then方法。
Promise.resolve(1).then(num => {
console.log(num)
});
复制代码
reject
方法接受一个参数,返回一个状态为失败的Promise对象,并将给定的失败信息传递给对应的处理方法。
Promise.reject('error');
// 等同于
new Promise((resolve, reject) => reject('error'))
复制代码
all
方法接受具备 iterable 接口 参数。
这个方法返回一个新的promise对象,该promise对象在iterable参数对象里全部的promise对象都成功的时候才会触发成功,一旦有任何一个iterable里面的promise对象失败则当即触发该promise对象的失败。
这个新的promise对象在触发成功状态之后,会把一个包含iterable里全部promise返回值的数组做为成功回调的返回值,顺序跟iterable的顺序保持一致
若是这个新的promise对象触发了失败状态,它会把iterable里第一个触发失败的promise对象的错误信息做为它的失败错误信息。
参数中的每一个项目都是一个 Promise 对象,若是不是则用 resolve
方法转换成 Promise 对象。
race
方法和 all
方法同样,可是当iterable
参数里的任意一个子 Promise 被成功或失败后,返回的 Promise 对象的状态就变成这个子 Promise 对象的状态,它的值或错误信息也会传递给返回 Promise 对象的回调函数。
Promise 一共有两个属性,length
和 prototype
。
length属性,其值老是为 1 (构造器参数的数目)。