一、问题来源。
有一个面试的题目,比如现在有N个ajax请求,但是有个逻辑是,必须要保证前面N个请求都已经完成的情况下
才能执行接下来的逻辑。如果做到呢。
二、一步步来实现。
2.1、如果,我们什么都不使用。
$.ajax({
url: url1,
success: function(data){
$.ajax({
url: url2,
data: data,
success: function(data){
$.ajax({
//...
});
}
});
}
});
比如上面的代码,如果有4个ajax请求,那么必须要嵌套4层。如果ajax越来越多,就会造成嵌套陷阱。
2.2、下面就来讲讲,嵌套陷阱,回调金字塔的解决方案。
很多框架,比如jquery、zepto、Q都实现了这样一个对象——Deferred。
export const wxGetLocation = ({ dispatch }, params) => {
let dfd = $.Deferred();
wx.getLocation({
type: 'wgs84',// 默认为wgs84的gps的坐标,如果要返回直接给openLocation用的火星坐标,可以传入gcj02
success: function (res) {
let data = {
'latitude': res.latitude, // 维度,浮点数,范围为90 ~ -90
'longitude': res.longitude, // 经度,浮点数,范围为180 ~ -180
'speed': res.speed, // 速度,以米/每秒计
'accuracy': res.accuracy, // 位置精度
};
dispatch('UPDATE_AGENT_LOCATION', data);
dfd.resolve();
}
});
return dfd.promise();
};
比如,我们看上面的代码首先在函数内部,定义了一个对象$.Deferred(); 这个对象有多种转态:肯定状态(resolved)、否定状态(rejected)、等待状态(pending),这几个状态分别对应:done()、fail()、progress()。新创建的Deferred肯定是pending状态了。
如果,我们要解决上面说到的嵌套调用的问题,可以使用下面的方式:
function ok(name){
var dfd = new $.Deferred();
callback:func(){
return dfd.resolve( response );
}
return dfd.promise();
}
$.when(ok(1),ok(2)).then(function(resp1,resp2){})
使用jquery中的$.when,当几个函数都完成时,才会执行then后面的逻辑。
3、具体的参考。
上面讲述的不是特别的仔细,需要阅读者,仔细阅读网上的资料,并且在实践中去体验这其中的内涵。
参考一:jquery.Deferred promise解决异步回调
参考二:jQuery deferred.promise() 方法