前言
ECMAScript 6 的正式版后,我们看到新增加了一个对象Promise
,它是用来处理异步操作的,以前的异步操作书写并不是很美观,而且在回调函数中 return
和 throw
并不会带到我们想要的状态。而Promise
很好的解决了这些问题。
了解 promise
promise 对象存在三种状态,进行中、结束、失败。当从进行中到结束状态或从进行中到失败状态时,会触发reslove
、reject
函数。
Promise 对象用法
// 创建 promise
let promise = new Promise(function(reslove,reject){
if(/ * 成功 */){
reslove(values) // 成功调用reslove函数
}else{
reject(values) // 失败调用 reject函数
}
})
// 调用
promise.then(function(val){
// 调用reslove() 函数
},function(val){
调用 reject() 函数
})
reslove
和 reject
函数并不我们自己声明的,而是js底层为我们封装好的。当我们在 promise
对象中成功时调用reslove
函数,它会触发then方法中的第一个函数,当我们在 promise
对象中成功时调用reject
函数,它会触发then方法中的第二个函数,另外then中的第二个方法我们可以省略。我们可以使用 catch
来接受一些错误信息。
promise.then((val) =>{
// 成功处理
}).catch((val) =>{
// 错误处理
})
在创建的promise
构造函数里或then
的回调函数里遇到的错误信息都会被catch
捕获到,我们来看一个例子
let promise = function(time){
return new Promise(function(relove, reject){
if(typeof time == 'number'){
setTimeout(relove,time,"调用成功");
}else{
reject("调用失败")
}
})
}
promise(100).then((val) =>{
console.log(val) // 调用成功
})
promise("fda").then((val) =>{
console.log(val) // 调用失败
})
promise(100).then((val) =>{
new throw("出错了")
console.log(val) // 不执行
}).catch((val) => {
console.log(val) //出错了
})
现在我们应该对promise有一定的了解,使用promise
还有一定的好处是,我们可以在then
回调函数中去使用 return
语句和 throw
语句,上面我们已经使用了throw
语句。另外我们还可以在then的回调函数中去使用调用另一 promise
对象。这样比我们使用AJAX交互时嵌套访问清晰的多。
promiseOne.then(()=>{
promiseTwo.then(() =>{
})
}).catch(() =>{
})
另外,我们应该知道,then
方法和 catch
方法是绑定到了 promise
对象的原型上边了。
Promise 对象的其他用法
1. Promise.all()
该方法用于将多个 Promise 实例,包装成一个新的 Promise 实例。
let promise = Promise.all([promiseOne,promiseTwo]);
这种情况下当 promiseOne
和 promiseTwo
都成功调用 promise
才会被成功调用,
2. Promise.race()
该方法同样是将多个Promise
实例,包装成一个新的Promise
实例。只不过在这种情况下,只要其中一个被成功调用,promise
就会被成功调用。
- Promise.resolve()
将对象转换为 Promise
,这里有四中情况
(1)参数是一个Promise实例
let promise = new Promise(function(relove,reject){
})
// 返回promise
let promiseNew = Promise.resolve(promise)
如果参数是Promise实例,那么Promise.resolve将不做任何修改、原封不动地返回这个实例。
(2)参数是一个thenable对象
thenable对象就是带有 then
方法的对象
let obj ={
then(relove,reject){
relove(111)
}
}
let promiseNew = Promise.resolve(obj)
promiseNew.then((val) =>{
console.log(val) // 111
})
这时Promise.resolve(obj)
会将obj转化为Promise
对象,并立即执行then方法
(3)参数不是具有then方法的对象,或根本就不是对象
let promiseNew = Promise.resolve(1234)
promiseNew.then((val) =>{
console.log(val) // 1234
})
(4)不带有任何参数
// 返回一个 relove状态的Promise对象
let promiseNew = Promise.resolve()
需要注意的是,立即resolve
的Promise对象,实在事件循环结束时,而不是开始时,如:
setTimeout(function(){
console.log(111)
})
Promise.resolve().then(() =>{
console.log(222)
})
console.log(333)
// 333
// 222
// 111
setTimeout
是在下一个事件循环时执行,Promise.reslove
是在事件循环结束是调用, console
是立即调用
- Promise.reject()
Promise.reject(reason)
方法也会返回一个新的 Promise 实例,该实例的状态为rejected
。
var p = Promise.reject('出错了');
// 等同于
var p = new Promise((resolve, reject) => reject('出错了'))
p.then(null, function (s) {
console.log(s)
});
// 出错了
注意,Promise.reject()方法的参数,会原封不动地作为reject的理由,变成后续方法的参数。这一点与Promise.resolve方法不一致。
- done()
该方法是Promise
对象的回调链,不管以then方法或catch方法结尾,要是最后一个方法抛出错误,都有可能无法捕捉到(因为Promise内部的错误不会冒泡到全局)。因此,我们可以提供一个done方法,总是处于回调链的尾端,保证抛出任何可能出现的错误。
promise.then()
.catch()
.then()
.catch()
.done() // 接收错误,并向全局抛出
- finally()
finally方法用于指定不管Promise对象最后状态如何,都会执行的操作。它与done方法的最大区别,它接受一个普通的回调函数作为参数,该函数不管怎样都必须执行。
promise.then()
.finally() // 不管then() 是否有错,finally都会执行
结束
promise 对象的使用并不是很难,这里我参考了阮一峰老师的书籍。
参考书籍:《ECMAScript 6 入门》
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。