2015-01-28 6 views
0

지연된/약속을 루프에서 사용하려고하는데 이상한 동작이 발생합니다.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)); 
    }); 

}); 

코드에 사용 된 물방울 내가 이미지에 대한 속성을 (그것이 정확히 말하면 filepicker.io의 pickandstore 방법에서 유래)이 포함되어 원격 웹 서비스에서 얻을 객체의 배열입니다 다음과 같이 내 코드는 . I이 실행할 때

, I는 콘솔 다음 얻을 :

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":"" 
    } 
] 

는 별도로 출력 할 때 이미지 [0] 및 이미지 [1] 정확하게 객체 어레이 회만 이미지 [1 음료수 있지만 ] !!!

내가 뭐 잘못하고 있니?

미리 감사드립니다.

UPDATE : 나는 그래서 당신의 images 배열의 모든 요소가 같은 객체를 가리키고, @TrueBlueAussie

+0

사이드 메모를

당신은 defer.resolve(i) 전화를 연기해야한다, 그래서 나중에 해결 될 것입니다 이연하여 수행 핸들러를 입력 : 당신은 DOM 준비 처리기에서 doAsyncOriginal''의 내부 코드를 래핑 . 호출 코드가 이미 하나로 묶여 있으므로 필요하지 않습니다. 즉, 즉각적으로 약속을 해결하는 것입니다. –

+0

Q : 이미지가 어느 시점에로드되는 것으로 가정합니까? –

+0

@TrueBlueAussie가 의견을 보내 주셔서 감사합니다. 나는 그들을 제거했지만 여전히 동일하게 작동합니다. 이 코드를 실행할 때 이미 이미지가로드되고 Blob 객체는 콜백 함수에서 반환됩니다. 내 문제는 루프와 관련이 있습니다. 배열의 모든 요소가 푸시 될 때 배열을 다른 함수로 전달하고 싶습니다. –

답변

2

당신은 doAsyncOriginal() 모든 호출에 같은 image 객체를 재사용하는의 의견에 따라 코드를 수정했습니다.

당신은 함수 내부의 객체를 생성해야합니다

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

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

    // ... 
} 

이 문제는 약속/deferreds 및 약속 관련이/정말 코드에서 어떤 목적을 제공하지 않습니다 deferreds. 당신은이 작업을 수행 할 수 있습니다 : 당신은 당신이이 약속이나 심지어에서 수행 핸들러를 추가하기 전에 반환하기 전에 연기 해결

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

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

예! 나는 내가 어리석은 짓을 한 것을 알았다. 감사합니다 !!! –

0

doAsyncOriginal에서. ...

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

    // ... 

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

    return defer.promise(); 
} 
+0

promise의'.done()'핸들러가 내장되어 있습니다. 수동으로 추가 할 필요는 없습니다. 여기서 당신이하는 일은 무의미합니다. – JLRishe

+0

@JLRishe 콜백 함수를 정의하는 것이 었습니다. 수정 해 주셔서 감사합니다. – NeoPix

+0

콜백 함수를 해결하기 전에 약속에 추가 할 필요는 없습니다. OP 코드의 약속은 잘 작동합니다. 문제는 약속과는 무관합니다. – JLRishe