场景:
当我们需要得到两个接口的结果后,才执行下一步逻辑时,举个栗子:
假如我们去相亲,需要知道对方的长相和家庭条件后,才进行下一步交往。
同步等待的做法:
var looks = 0 // 长相0分
var money = 0 // 条件0分
// 线下获取长相
getLooks: function() {
$.ajax({
url: 'xxx',
async: false, // 同步执行
success: function(res) {
// 长得可以,100分
looks = 100
}
})
}
// 线下询问家庭条件
getMoney: function() {
$.ajax({
url: 'xxx',
async: false, // 同步执行
success: function(res) {
// 条件可以,100分
money = 100
}
})
}
getLooks()
getMoney()
// 不过不设置同步 async: false,此处判断只会是false
if (looks && money) {
// 长相,家庭条件都可以,进一步交往
contact()
} else {
// 不满意,继续逛街
shopping()
}
这种做法需要先见面判断,然后等待结果,才能进行下一步操作,同步的方式也阻碍了我逛街的进程。
异步等待的做法:
// 微信拍照获取长相
getLooks: function() {
$.ajax({
url: 'xxx',
success: function(res) {
// 长得可以,问他家庭条件
getMoney()
}
})
}
// 微信询问家庭条件
getMoney: function() {
$.ajax({
url: 'xxx',
success: function(res) {
// 条件可以,进一步交往
contact()
}
})
}
getLooks()
shopping()
这种做法可以判断与逛街同时进行,不会阻碍逛街的进程,"一问一答"的方式,但是一旦判断条件多了,比如还需判断家庭情况,文化水平等等,要等待上一个问题的答案,会出现层层嵌套的问题。
异步优雅的做法:
// 获取长相
getLooks: function() {
var def = $.Deferred() // 延迟等待调用
$.ajax({
url: 'xxx',
success: function(res) {
def.resolve(res)
}
})
}
// 家庭条件
getMoney: function() {
var def = $.Deferred() // 延迟等待调用
$.ajax({
url: 'xxx',
success: function(res) {
def.resolve(res)
}
})
}
// 一次性把条件问完,只需等待所有结果一起返回,直接做判断
$.when(getLooks(), getMoney()).then(function(looks, money){
// 各方面条件可以,进一步交往
contact()
}, function(looks,money){
console.log('不合适,继续逛街')
})
shopping()
这种做法不会阻碍逛街的进程,所有判断条件也可以一次性执行,不需要等待一个个执行,只需等待所有结果都返回,便可做出判断。
小结:
1、接口请求避免使用同步方式,会阻碍进程,出现页面假死状态,交互非常不友好。
2、当需要多个接口结果时,可以使用.when()的方式。
3、此外,Deferred还有always()方法,用于:无论接口是否成功,都执行下一步操作。
参考文档:
阮一峰 -《jQuery的deferred对象详解》