promise和deferred
之前在公司做的一个微信公众号调用微信中的拍照的接口代码:
wx.chooseImage({
success: function (res) {
wx.uploadImage({
success: function (res) {
$.ajax({
success: function (data) {}
})
}
});
}
})
以上代码多层回调,形成回调地狱,再加上业务逻辑代码后非常混乱,很不直观。
promise的出现是为了解决写多个异步操作嵌套的问题,在控制台打印可以看出是一个函数,这个promise其实是一个构造函数。
promise提供常用的方法:
resolve
方法可以使 promise 对象的状态改变成成功,同时传递一个参数用于后续成功后的操作
reject
方法则是将 Promise 对象的状态改变为失败,同时将错误的信息传递到后续错误处理的操作
then方法用的链式调用,接收参数是两个函数,第一个函数是响应的是resolve(),第二个函数是响应reject()
catch方法用于捕获之前代码中的错误
function Request (url,type) {
return new Promise(function (resolove,reject) {
$.ajax({
url:url,
type:type
success: function (res) {
for(var i=0,l=100; i<l; i++ ) {
console.log(i)
}
resolve(res);
},
fail: function (res) {
reject(res);
}
})
})
}
// Promise的代码执行顺序是会根据接口的成功与否,进入suc或者fail,当进去suc的时候,会把suc函数里的代码全部执行完,再去执行触发resolve后面的代码,即使resolve()执行位置是在suc内的首行执行,后续代码也会执行完毕后,再执行then的代码
Request()
.then(function (data) {
//此data为resolve(res)传递的参数;成功的回调
Request()
},
function (data) {
//此data为reject(res)传递的参数;失败的回调
})
.then(function () {})
.catch(function () {});
all方法:
Promise.all([request1(),request()2,request()])
.then(function (res) {})
request1,2,3是并行执行的,当这三个请求都是中都是resolve()的时候才走then的第一个方法,三个请求返回的数据在then的第一个方法中,并且是以为数组的形式保存。
promise其他几点:
1.then方法是等待返回结果的,所以是异步的,之前的操作还是同步的
2.构造函数中的resolve 或 reject 只有第一次执行有效,多次调用没有任何作用。promise状态一旦改变则不能再变。
jquery中的deferred对象,是jquery的回调的解决方案。在jquery1.5版本之前ajax返回一个XML对象,1.5之后返回deferred对象,可以进行链式调用。
对于普通函数的回调,也可以用deferred实现
var task = function () { var dtd = $.Deferred(); $.ajax({ url:'', type:'', success: function () { dtd.resolve(); } }) return dtd.promise(); } $.when(task()).then(function () { //suc })
常用方法:
1. $.Deferred() 生成一个deferred对象
2. deferred.done() 成功的回调函数
3. deferred.fail() 失败的回调函数
4. deferred.resolve() 手动改变deferred对象的运行状态,触发done()方法
5. deferred.reject() 手动改变deferred对象的运行状态,触发fail()方法
6. $.when() 为多个操作指定回调函数。
7. deferred.then();
8. deferred.always();