2017-03-03 37 views
0

我正在創建一個函數,以在需要時使用延遲加載圖像(使用分頁將大數據集劃分爲更小的塊)。等待數組內部的嵌套承諾

問題是承諾嵌套在items[i].imagedata

返回的items數組仍然包含Promise對象而不是加載的圖像。這可能是因爲我使用items.map(),它創建了數組的副本。

function getItemImages(items, paging, cb) { 
    var Promise = promise.Promise; 
    console.log("START",items,paging); 
    for (var i=paging.pageOffset; i<Math.min(paging.pageOffset+paging.pageLimit,items.length); i++) { 
     if (!items[i].hasOwnProperty("imagedata")) { 
      console.log("LOADING "+i+":",items[i]); 
      items[i].imagedata = mongodbService.getItemImage(items[i]._id); 
     } 
    } 
    Promise.all(items.map((item) => { 
     return Promise.all([item.imagedata]); 
    })).then((images) => { 
     console.log("RESULT",paging, items); 
     cb(paging, items); 
    }); 
} 
+0

你想使用返回'images',而不是原來'items' – Bergi

+0

'返回Promise.all([item.imagedata]);'出現相當沒有意義的。我想你可以把它減少到'return item.imagedata;' – Bergi

回答

1

你是對的。 promise解析器不會在另一個對象內搜索promise。你需要爲你想要完成的事情返回一個承諾,儘管你可以做到這一點。在這裏,我添加了一個單獨的函數,該函數通過鏈接getItemImage promise結果來突變.imagedata,從而爲items [i]返回promise。這個承諾反過來應該可以與所有人一起使用,這樣Promise.all會在所有圖像發生變異時觸發。

除非您在某個需要回調參數的地方完成遺留接口,否則最好在最後返回Promise.all(承諾),以便調用者可以決定是否通過自己的方式直接回調回調或將更多操作鏈接到諾言解決方案以及如何處理錯誤。

function getItemImages(items, paging, cb) { 
    var Promise = promise.Promise; 
    console.log("START",items,paging); 
    // Return a promise for items[i] with .imagedata 
    function promiseImage(i) { 
     return mongodbService.getItemImage(items[i]._id). 
      then(function(image) { 
       items[i].imagedata = image; 
       return items[i]; 
      }); 
    } 
    var promises = []; 
    for (var i=paging.pageOffset; i<Math.min(paging.pageOffset+paging.pageLimit,items.length); i++) { 
     if (!items[i].hasOwnProperty("imagedata")) { 
      console.log("LOADING "+i+":",items[i]); 
      // Add a new promise to promises 
      promises.push(promiseImage(i)); 
     } 
    } 
    // promises is an array of promises, so "all" will work. 
    // Your code uses mutation, so the result isn't needed here. 
    // Previously, items was being sent to cb. 
    // cb might also consume the actual list of mutated items 
    // below. 
    Promise.all(promises). 
     then(() => { 
      console.log("RESULT",paging, items); 
      cb(paging, items); 
     }); 
}