2017-08-13 72 views
1

我有一個函數可以將畫布圖像重新抽樣到第二個畫布。據我瞭解,通過使用then,它使用承諾,並幫助我獲得延遲return,而不是得到undefined如果return來得太早。鏈中的承諾錯誤理解

function resample_sizeo(canvas, width, height) { 

    // Initialize 
    var resizer = sizeo(); 

    var canvasResampled = document.createElement('canvas'); 
    canvasResampled.width = width; 
    canvasResampled.height = height; 
    // Function using two canvas' in the form of: resize(from, to) 
    return resizer.resize(canvas, canvasResampled) 
    // Function that converts resampled canvas to a data blob 
    .then(result => resizer.toBlob(result, 'image/jpeg', 95)) 
    // End with a blob to return 
    .then(blob => blob); 
} 

裸陪我在這裏,因爲我清楚地犯了一個錯誤,但我想步我的理解:

我想鏈通話一起ňresample_sizeo和依次運行它們。這是我看到的一個受歡迎的請求,我也看到它與await/async很好地解決,但我不能使用這些,因爲我不會在這裏進入。

我用Promise-Waterfall等一些腳本非常接近,但發現我試圖滿足它的承諾返回函數的數組是兩倍我的代碼,也許 - 也許 - 如果我已經有一個函數那個答應了。也許我過於簡單,我已經完成了90%的工作。所以我試着回到我的朋友then。當然,如果我的函數已經返回一個承諾,我可以將一些調用鏈接在一起?

resample_sizeo(sourceCanvas, widthsRequired[0], heightsRequired[0]) 
.then(function(result) { // (**) 
    console.log(result); 
    resampledImageBlobs[0] = result; 
    resample_sizeo(sourceCanvas, widthsRequired[1], heightsRequired[1]) 
}).then(function(result) { // (***) 
    resampledImageBlobs[1] = result; 
    resample_sizeo(sourceCanvas, widthsRequired[2], heightsRequired[2]) 
}).then(function(result) { 
    resampledImageBlobs[2] = result; 
    resample_sizeo(sourceCanvas, widthsRequired[3], heightsRequired[3]) 
}).then(function(result) { 
    resampledImageBlobs[3] = result; 
    console.log("All done", resampledImageBlobs); 
    uploadImageBlobSet(resampledImageBlobs, 'replace'); 
}); 

這沒有奏效。 resampledImageBlobs最後顯示它是[blob,undefined,undefined,undefined],所以它沒有等到每個函數在結束之前完成。我忽略了一些東西。如果我單獨檢查這些調用的結果,它們會返回一個blob。但他們並沒有按順序連續輪流等待。

+1

你'return'內'resample_sizeo(...)'從承諾'然後'回調,否則下一個承諾將不知道等待什麼 – Bergi

回答

1

您需要退還resample_sizeo的承諾。否則,你要.then(...)下一個電話就會立即運行,並且result參數將是一個功能的通常的返回值,這是undefined

resample_sizeo(sourceCanvas, widthsRequired[0], heightsRequired[0]) 
.then(function(result) { // (**) 
    console.log(result); 
    resampledImageBlobs[0] = result; 
    return resample_sizeo(sourceCanvas, widthsRequired[1], heightsRequired[1]) 
}).then(function(result) { // (***) 
    resampledImageBlobs[1] = result; 
    return resample_sizeo(sourceCanvas, widthsRequired[2], heightsRequired[2]) 
}).then(function(result) { 
    resampledImageBlobs[2] = result; 
    return resample_sizeo(sourceCanvas, widthsRequired[3], heightsRequired[3]) 
}).then(function(result) { 
    resampledImageBlobs[3] = result; 
    console.log("All done", resampledImageBlobs); 
    uploadImageBlobSet(resampledImageBlobs, 'replace'); 
}); 
+0

非常感謝弗蘭克!我花了大約14小時嘗試各種技術,非常高興,我意識到我的原始代碼比答案中的所有兔子洞更接近答案。我仍然對自己的承諾感到滿意,錯過了需要回報的地方,就像你提到的那樣。在上下文中似乎很明顯,但我認爲我的頭仍然混亂。 – biscuitstack

+0

@biscuitstack不客氣,這是一個常見的錯誤:) –