Javascript jQuery延迟/承诺
我试图在循环中使用延迟/承诺,但我得到了奇怪的行为。我的代码如下:Javascript jQuery延迟/承诺,javascript,jquery,arrays,promise,deferred,Javascript,Jquery,Arrays,Promise,Deferred,我试图在循环中使用延迟/承诺,但我得到了奇怪的行为。我的代码如下: var images = []; var numImages = Blobs.length; var image = {}; console.log("numImages: " + numImages); function doAsyncOriginal(i) { var defer = $.Deferred(); image.original = Blobs[i].key; image.resize
var images = [];
var numImages = Blobs.length;
var image = {};
console.log("numImages: " + numImages);
function doAsyncOriginal(i) {
var defer = $.Deferred();
image.original = Blobs[i].key;
image.resized = '';
image.thumbnail = '';
images.push(image);
console.log("i: " + i + " image: " + image.original);
console.log("images[" + i + "]: " + images[i].original);
defer.resolve(i);
return defer.promise();
}
$(function(){
var currentImage = doAsyncOriginal(0);
for(var i = 1; i < numImages; i++){
currentImage = currentImage.pipe(function(j) {
return doAsyncOriginal(j+1);
});
}
$.when(currentImage).done(function() {
console.log(JSON.stringify(images));
});
});
虽然它正确显示图像[0]和图像[1],但单独打印时,对象数组仅显示两次图像[1]
我做错什么了吗
提前感谢您抽出时间
更新:我根据@TrueBlueAussie的注释更正了代码在每次调用
doAsyncOriginal()
时,您都在重用相同的image
对象,因此images
数组的每个元素都指向相同的对象
您需要在函数中创建对象:
var image = {}; // <-- delete this
function doAsyncOriginal(i) {
var image = {};
// ...
}
在
doAsyncOriginal
中,您可以在返回延迟的承诺之前,甚至在向其添加完成处理程序之前,解析延迟
您应该延迟defer.resolve(i)
调用,以便稍后解析延迟,并输入done处理程序
function doAsyncOriginal(i) {
var defer = $.Deferred();
// ...
// Function.bind equivalent to jQuery.proxy
window.setTimeOut(defer.resolve.bind(defer, i), 0);
return defer.promise();
}
旁注:您正在DOM就绪处理程序中包装
doAsyncOriginal
中的代码。这是不需要的,因为调用代码已经包装在一个中。这也意味着您正在立即解决这些承诺。问:这些图片假定在什么时候加载?@TrueBlueAussie感谢您的评论,我删除了它们,但仍然有效。运行此代码时图像已经加载,Blob对象从回调函数返回。我的问题与循环有关。我想在推送数组的所有元素时将数组传递给另一个函数。promise上的.done()
处理程序是内置的。它不必手动添加。您在这里所做的是毫无意义的。@JLRishe我的意思是定义回调函数,感谢您的更正。回调函数在解析之前不必添加到承诺中。OP代码中的承诺运行良好。这个问题与承诺无关。@JLRishe那么,对于已解决的承诺,如果我定义了一个已完成的回调,那么回调是否仍被调用?如何管理此调用(在堆栈中,延迟)?是的,这是正确的。在符合承诺/A+的承诺中,对处理程序的调用必须延迟(),但看起来已经解析的jQuery承诺会立即调用其处理程序:
$(function(){
var images = Blobs.map(function (blob) {
return {
original: blob.key,
resized: '',
thumbnail: ''
};
});
console.log(JSON.stringify(images));
});
function doAsyncOriginal(i) {
var defer = $.Deferred();
// ...
// Function.bind equivalent to jQuery.proxy
window.setTimeOut(defer.resolve.bind(defer, i), 0);
return defer.promise();
}