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();
}