2017-03-03 35 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); 
     }); 
}