我刚刚开始使用promises,我可以使用一些指导如何使这个场景工作。下面的代码来自一个更大的插件文件,但我刚刚包含了我认为相关的部分。
有一个回调函数(callbackBeforeSend),我将执行一些异步地理位置(我已经完成了这个工作)并且我需要保持ajax调用,直到这些函数完成。
我在代码中看到他们使用$ .Deferred()来处理ajax响应,我想知道是否有办法将回调函数和初始ajax调用绑定到$ .Deferred()以及处理所有事情的正确执行顺序。
所以我想要发生的是
非常感谢任何帮助。我仍然不太了解承诺,但我正在努力学习。谢谢!
$.extend(Plugin.prototype, {
_getData: function (lat, lng, address) {
var _this = this;
var d = $.Deferred();
if (this.settings.callbackBeforeSend) {
this.settings.callbackBeforeSend.call(this, lat, lng, address);
}
$.ajax({
type : 'GET',
url : this.settings.dataLocation + (this.settings.dataType === 'jsonp' ? (this.settings.dataLocation.match(/\?/) ? '&' : '?') + 'callback=?' : ''),
// Passing the lat, lng, and address with the AJAX request so they can optionally be used by back-end languages
data: {
'origLat' : lat,
'origLng' : lng,
'origAddress': address
},
dataType : dataTypeRead,
jsonpCallback: (this.settings.dataType === 'jsonp' ? this.settings.callbackJsonp : null)
}).done(function (p) {
d.resolve(p);
// Loading remove
if(_this.settings.loading === true){
$('.' + _this.settings.formContainer + ' .' + _this.settings.loadingContainer).remove();
}
}).fail(d.reject);
return d.promise();
}
});
答案 0 :(得分:0)
我真的不喜欢jQuery的承诺,但如果你必须......
function callBackBeforeSend(){
var def = $.Deferred();
//Async operation here:
async(function(lat, lng, address) {
//pass resolve an object with all information
//the async callback function might not use 3 parameters, but an
//object containing all
def.resolve({ lat : lat, lng : lng, address : address});
//async function callback
});
return def.promise();
}
然后,您可以使用deferred.then()
来获取已解析的数据。
var prom = callbackBeforeSend();
prom.then(function(obj){
//lat, lng, address within obj
//use on ajax call below.
$.ajax();
});
然后,您可以使用then
来链接方法
我还要查看你正在使用的jQuery版本。 jQuery 1.8之前的行为可能会有所不同。
这是使用ES6承诺:
function callbackBeforeSend(){
return new Promise(function(resolve) {
async(function(lat, lng, address){
resolve({lat : lat, lng : lng, address : address});
});
});
}
那就是同样的事情:
var prom = callbackBeforeSend(); //firstRequest
prom.then(function(obj){
//Callback finished
//obj holds lat, lng, address
//Do ajax request:
$.ajax();
});
答案 1 :(得分:0)
- 回调功能触发
- 异步内容发生在回调和返回中 lat,lng,地址
- Ajax使用lat,lng,地址触发 从回调中返回
醇>
$.when(callback())
.then(function(data) {
// `data`: `lat` , `lng`, `address` ...
var settings = {url:url, data:{...}, type:"GET"};
return $.ajax(settings)
}, function(jqxhr, textStatus, errorThrown) {
console.log(errorThrown);
return errorThrown
})
.then(function(data) {
// do stuff when `callback` , `$.ajax()` completes
}, function(err) {
console.log(err);
});
答案 2 :(得分:0)
可能最重要的事情是:
callbackBeforeSend()
,要求Promise由callbackBeforeSend()
返回或创建。$.ajax()
返回一个jqXHR
对象,实际上是一个Promise,因此$.ajax()
不需要您创建/解析自己的Deferred。 试试这个:
$.extend(Plugin.prototype, {
_getData: function (lat, lng, address) {
var settings = this.settings;
var promise = settings.callbackBeforeSend ? $.when(settings.callbackBeforeSend.call(this, lat, lng, address)) : $.when();
return promise.then(function() {
return $.ajax({
type: 'GET',
url: settings.dataLocation + (settings.dataType === 'jsonp' ? (settings.dataLocation.match(/\?/) ? '&' : '?') + 'callback=?' : ''),
data: { 'origLat':lat, 'origLng':lng, 'origAddress':address },
dataType: dataTypeRead,
jsonpCallback: (settings.dataType === 'jsonp' ? settings.callbackJsonp : null)
});
}).then(null, function(jqXHR, textStatus, errorThrown) {
return errorThrown;
});
}
});
如果settings.callbackBeforeSend()
已经返回了一个承诺,则可以免除$.when(...)
包装。
你的" loading"指示应该(通过惯例)附加并随后在相同的代码块中删除 - 在_getData()
内或在调用函数中。
例如,调用函数可能会调用._getData()
并按如下方式对其结果进行操作:
var $spinner = $("#myLoadingElement").appendTo('.wherever');//pseudocode
foo._getData(lat, lng, address).then(function(data) {
//do whatever on success
}, function(error) {
//do whatever on error
}).always(function() {
$spinner.remove();//remove the spinner regardless of the outcome.
});