我正在创建一个函数来在需要时延迟加载图像(使用分页将大数据集分成更小的块)。
问题是 Promise 嵌套在
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);
});
}
你是对的。 承诺解析器不会在另一个对象中搜索承诺。 你需要对你想要完成的整个事情做出承诺,尽管你可以分段完成。 在这里,我添加了一个单独的函数,该函数返回 items[i] 的承诺,其中 .imagedata 通过链接 getItemImage 承诺结果而发生变化。 该 Promise 反过来应该适用于所有图像,以便 Promise.all 在所有图像发生变异时触发。
除非您在需要回调参数的地方实现遗留接口,否则最好在最后返回 Promise.all(promises) ,以便调用者可以决定是否通过自己的回调或链直接回调有关承诺解析的更多操作以及如何处理错误。
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);
});
}