相信没有JQuery.promise 和ES6 Promise 在做异步数据合并等情况时 内心应该是崩溃的 不知不觉低就看到了回调地狱,维护和开发成本也上升了,但是现在promise情况会好很多.那我们就来看下什么是 promise.
描述
Promise
对象是一个代理对象(代理一个值),被代理的值在Promise对象创建时可能是未知的。它允许你为异步操作的成功和失败分别绑定相应的处理方法(handlers)。 这让异步方法可以像同步方法那样返回值,但并不是立即返回最终执行结果,而是一个能代表未来出现的结果的promise对象
一个 Promise
有以下几种状态:
- pending: 初始状态,既不是成功,也不是失败状态。
- fulfilled: 意味着操作成功完成。
- rejected: 意味着操作失败。
方法
-
这个方法返回一个新的promise对象,该promise对象在
param
参数对象里所有的promise对象都成功的时候才会触发成功,一旦有任何一个param对象 里面的promise对象失败则立即触发 都会认为该promise对象的失败。Promise.all方法常被用于处理多个promise对象的状态集合。 - 当iterable参数里的任意一个子promise被成功或失败后, 父promise马上也会用子promise的成功返回值或失败详情作为参数调用 父promise绑定的相应后续处理,并返回该promise对象。
Promise.all(param...)
Promise.race(iterable...)
- 返回一个状态为失败的Promise对象,并将给定的失败信息传递给对应的处理方法
Promise.reject(reason)
返回一个状态由给定value决定的Promise对象。如果value
是一个Promise对象,则直接返回该对象;如果该值是thenable(即,带有then方法的对象),返回的Promise对象的最终状态由then方法执行决定;否则的话(该value为空,基本类型或者不带then方法的对象),返回的Promise对象状态为fulfilled,并且将该value传递给对应的then方法。通常而言,如果你不知道一个值是否是Promise对象,使用Promise.resolve(value) 来返回一个Promise对象,这样就能将该value以Promise对象形式使用。
Promise 原型
- 添加一个拒绝(rejection) 回调到当前 promise, 返回一个新的promise。当这个回调函数被调用,新 promise 将以它的返回值来resolve,否则如果当前promise 进入fulfilled状态,则以当前promise的完成结果作为新promise的完成结果.
- 添加解决(fulfillment)和拒绝(rejection)回调到当前 promise, 返回一个新的 promise, 将以回调的返回值来resolve.
- 添加一个事件处理回调于当前promise对象,并且在原promise对象解析完毕后,返回一个新的promise对象。回调会在当前promise运行完毕后被调用,无论当前promise的状态是完成(fulfilled)还是失败(rejected)
Promise.prototype.catch(onRejected)
Promise.prototype.then(onFulfilled, onRejected)
Promise.prototype.finally(onFinally)
创建Promise
let promise = new Promise ( (resolve, reject) => { //实例化(new)过程中Promise对象会立即执行
if ( success ) {
resolve(a) // pending ——> resolved 参数将传递给对应的回调方法
} else {
reject(err) // pending ——> rejectd 状态从初始化置为失败
}
} )
示例
let _b=new Promise((resolve,reject)=>{
//这里主要处理异步数据请求 或者说耗时很长不确定时间因素等代码
//接收成功后我们将调用resolve 传入获取到的参数, 失败则调用reject
//这里我们用setTimeout 模拟AJAX请求
//resolve传入的参数类型不一定是一个对象 也可以是字符 数字 或者 Promise
setTimeout(()=>resolve({name:'小明'}),500)
})
//接下来我们可以做后面延续处理 then()//可写入两个参数 第一个是resolve回调,第二个是reject回调
_b.then((sMsg)=>{
//在这里我们将接收到来自 上面resolve的值
console.log(sMsg);
console.log("我的名字是:"+sMsg.name);
})
那我们完整的来测试下:
//我们得到一个随机值 如果在小于1的情况下 成功 不然则失败
var _p = new Promise((resolve, reject)=>{
console.log('start new Promise...');
var timeOut = Math.random() * 2;
console.log('set timeout to: ' + timeOut + ' seconds.');
setTimeout(()=> {
if (timeOut < 1) {
console.log('call resolve()...');
resolve('200 OK');
} else {
console.log('call reject()...');
reject('timeout in ' + timeOut + ' seconds.');
}
}, timeOut * 1000);
})
// 不管是 then catch 都会返回一个新的Promise对象 所以可以链式调用
_p.then((r)=> {
console.log('Done: ' + r);
}).catch((reason)=> { //catch 是捕获Promise错误 rejected 和 throw new Error() 都能触发 作用也相同
console.log('Failed: ' + reason);
throw new Error("又出错误了"); //同样的 catch中也能抛出异常 这时只能下一个catch捕获到
}).catch((reason)=> { // 捕获到上一个catch 里面抛出的错误
console.log('Failed2: ' + reason);//log:又出错误了
}).finally(()=>{
//finally会在当前promise运行完毕后被调用,无论当前promise的状态是完成(fulfilled)还是失败(rejected)
//PS:这个地方让和C#里面的try.catch.finally类似
console.log("你甩不掉我的");
});
注意:当Promise的状态已经改变为resolved后,即使抛出错误,也不会触发then()的错误回调或者catch()方法
Promise或者then中返回Promise
var _a=new Promise((resolve, reject)=>{reject('失败了')});
var _b = new Promise((resolve, reject)=>{
resolve(_a)
})
_b.then((r)=> {
console.log('Done: ' + r);
}).catch((reason)=> { //catch 是捕获当前的Promise错误
console.log('Failed: ' + reason);
})
上面的例子中_b的状态取决于_a 如果_a没有返回状态时 _b状态为pending 如果_a状态改变_b也会随之。
Promise.all()
var promiseGather = Promise.all( [_a, _b, _c] )
promiseGather.then(
...
).catch(
...
)
all的参数为Promise对象数组,传入的Promise对象数组里面有不是Promise的对象,将会先通过Promise.resolve()方法转换
当_a, _b, _c的状态都变成resolved时,promiseGather才会变成resolved,并调用then()的已完成回调,一旦有任何一个Promise对象失败则立即触发rejected状态 都会认为该promiseGather对象的失败。
Promise.race()
var promiseGather = Promise.race( [_a, _b, _c] )
promiseGather.then(
...
).catch(
...
)
rece 参数和all格式相同 ,但是race 是传入的Promise集合中有一个状态为fulfilled则继续执行下面的回调
Promise的兼容性
参考:
https://www.liaoxuefeng.com/wiki/001434446689867b27157e896e74d51a89c25cc8b43bdb3000/0014345008539155e93fc16046d4bb7854943814c4f9dc2000
https://www.jianshu.com/p/c98eb98bd00c
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Promise