gpt4 book ai didi

javascript - 在解决之前,我的 jquery $.Deferred 不会阻止另一个 $.ajax 调用的发生

转载 作者:行者123 更新时间:2023-11-30 12:41:53 29 4
gpt4 key购买 nike

我正在使用长轮询来检索带有图像 URL 的大型 json 提要。我在我的 $.ajax 请求的 success 部分预加载这些 url,并希望在它们完全加载后调用一个函数来对这些图像执行某些操作。我试图通过在我的 $.ajax 请求的 complete 部分使用 $.Deferred 对象,并解析 $.Deferred 在我的图像预加载循环结束时。

但是,当我监视控制台时,我可以看到在预加载图像时继续进行 $.ajax 调用。 $.Deferred 直到预加载循环结束才解析,所以我不明白为什么会发生这种情况。我对 $.Deferred 的了解有限,但我正在尝试了解更多信息,因此任何关于为什么会发生这种情况以及如何解决此问题的建议都会很棒。我得到的理解是,它们是一种防止函数被调用的方法,直到它们被保留...

作为奖励,除了丑陋的代码之外,发出多个 $.ajax 请求并对返回的数据执行相同的操作是否存在问题?谢谢

$(function(){
(function poll(){
var streamUrl = 'http://demofeed';
var def = $.Deferred();
console.log('about to get');
setTimeout(function(){
$.ajax({
url: streamUrl,
dataType: 'json',
success: function(data) {
createArray(data, def);
},
complete: function () {
$.when(def).done(function() {
//Long-poll again
poll();
});
},
error: function(){
setTimeout(function(){
console.log('There was an error with the XHR Request');
poll();
}, 3000);
}
});
}, 7000);
})();
});


function createArray(data, defer){
console.log('creating array');
var entries = data['entries'];
for (var k = 0, j = entries.length; k < j; k++) {
console.log('there is new media');
if (entries[k].img) {
var img = new Image();
img.onload = (function(entry) {
return function() {
validArray.push(entry);
console.log('New Media Loaded');
}
})(entries[k]);
img.onerror = function(){
console.log('error: bad image source');
};
img.src = entries[k].url;
} else {
console.log('Not an image');
}
}
defer.resolve(); //Here is where I resolve the deferred object, once for loop is done (all images have been loaded)
}

最佳答案

$.when 等待 promise

您传递给它的是一个延迟对象。它又通过包装转换为 promise ,因此等待它会立即产生它作为值。所以 .when 立即执行。您可以改为使用 def.promise() 来获得它的 promise 。

也就是说,如果我是你,我可能会做一个总体上更 promified 的 API。

var delay = function(ms){
var def = $.Deferred();
setTimeout(function(){ def.resolve(); },ms);
return def.promise();
}

哪个会让我做:

function poll(){
console.log('about to get');
return delay(7000).then(function(){
return $.get('http://demofeed');
}).then(function(){ // success case
return createArray(data); // we'll get to it later
}), function(){ // handle error
console.log('There was an error with the XHR Request');
return delay(3000); // wait 3 ms
}).then(poll); // long poll
}

看它多么清晰,它只有两级缩进,这是因为 promises 链。如果您的代码是顺序的,则大致如下:

  function poll(){
sleep(7000);
try{
var data = $.get('http://demofeed'); // assume this is sync
arr = createArray(data);
} catch(e) {
console.log("There was an error with the XHR Request");
sleep(3000);
}
poll(); /// call again
}

至于加载图像功能,考虑在其上使用$.when.apply$.when 等待多个值:

function createImages(data){ // what does this return?
var promises = data.entries.map(function(entry){
var img = new Image();
var d = $.Deferred();
img.onload = function(entry){ d.resolve(entry); };
img.onerror = function(){ console.log("Bad Image usage"); }
return d.promise();
});
// this will actually _wait_ for the images now.
return $.when.apply($, promises);
}

最后请注意,如果我是你,我会避免使用 jQuery promises 并使用功能更强大的库,如 Bluebird。

关于javascript - 在解决之前,我的 jquery $.Deferred 不会阻止另一个 $.ajax 调用的发生,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24152332/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com