簡體   English   中英

jQuery延遲/承諾

[英]jQuery Deferred / Promise

我試圖在循環中使用延期/承諾,但是我得到了奇怪的行為。 我的代碼如下:

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

});

代碼中使用的Blob是我從遠程Web服務獲得的對象數組,其中包含有關圖像的屬性(確切地說,它來自filepicker.io的pickandstore方法)。

運行此命令時,在控制台中得到以下信息:

numImages: 2
i: 0  image: pictures_originals/3QnQVZd0RryCr8H2Q0Iq_picture1.jpg
images[0]: pictures_originals/3QnQVZd0RryCr8H2Q0Iq_picture1.jpg
i: 1  image: pictures_originals/MD3KO6GjT8SNFYoPcG8J_picture2.jpg
images[1]: pictures_originals/MD3KO6GjT8SNFYoPcG8J_picture2.jpg

[
    {
        "original":"pictures_originals/MD3KO6GjT8SNFYoPcG8J_picture2.jpg",
        "resized":"",
        "thumbnail":""
    },
    {
        "original":"pictures_originals/MD3KO6GjT8SNFYoPcG8J_picture2.jpg",
        "resized":"",
        "thumbnail":""
    }
]

盡管它正確顯示了images [0]和images [1],但是當單獨打印時,對象數組僅顯示兩次images [1]!

難道我做錯了什么???

在此先感謝您的時間。

更新:我根據@TrueBlueAussie的評論更正了代碼

您將在對doAsyncOriginal()每次調用中重用同一image對象,因此, images數組的每個元素都指向同一對象。

您需要在函數內部創建對象:

var image = {};  // <-- delete this

function doAsyncOriginal(i) {
    var image = {};

    // ...
}

這個問題與承諾/延期無關,並且承諾/延期在您的代碼中實際上沒有任何作用。 您可以這樣做:

$(function(){
    var images = Blobs.map(function (blob) {
        return { 
            original: blob.key,
            resized: '',
            thumbnail: ''
        };
    });

    console.log(JSON.stringify(images));
});

doAsyncOriginal您可以在返回promise或什至在其上添加done處理程序之前解決延遲的問題。

您應該延遲defer.resolve(i)調用,以便稍后解決deferred並輸入完成的處理程序...

function doAsyncOriginal(i) {
    var defer = $.Deferred();

    // ...

    // Function.bind equivalent to jQuery.proxy
    window.setTimeOut(defer.resolve.bind(defer, i), 0);

    return defer.promise();
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM