ECMAScript 6 的正式版后,咱们看到新增长了一个对象Promise
,它是用来处理异步操做的,之前的异步操做书写并非很美观,并且在回调函数中 return
和 throw
并不会带到咱们想要的状态。而Promise
很好的解决了这些问题。es6
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交互时嵌套访问清晰的多。code
promiseOne.then(()=>{ promiseTwo.then(() =>{ }) }).catch(() =>{ })
另外,咱们应该知道,then
方法和 catch
方法是绑定到了 promise
对象的原型上边了。对象
1. Promise.all() 事件
该方法用于将多个 Promise 实例,包装成一个新的 Promise 实例。ip
let promise = Promise.all([promiseOne,promiseTwo]);
这种状况下当 promiseOne
和 promiseTwo
都成功调用 promise
才会被成功调用,get
2. Promise.race() 原型
该方法一样是将多个Promise
实例,包装成一个新的Promise
实例。只不过在这种状况下,只要其中一个被成功调用,promise
就会被成功调用。
将对象转换为 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(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方法不一致。
该方法是Promise
对象的回调链,无论以then方法或catch方法结尾,要是最后一个方法抛出错误,都有可能没法捕捉到(由于Promise内部的错误不会冒泡到全局)。所以,咱们能够提供一个done方法,老是处于回调链的尾端,保证抛出任何可能出现的错误。
promise.then() .catch() .then() .catch() .done() // 接收错误,并向全局抛出
finally方法用于指定无论Promise对象最后状态如何,都会执行的操做。它与done方法的最大区别,它接受一个普通的回调函数做为参数,该函数无论怎样都必须执行。
promise.then() .finally() // 无论then() 是否有错,finally都会执行
promise 对象的使用并非很难,这里我参考了阮一峰老师的书籍。
参考书籍:《ECMAScript 6 入门》