【问题标题】:Waiting for nested promises inside an array等待数组中的嵌套承诺
【发布时间】:2017-03-03 20:18:46
【问题描述】:

我正在创建一个函数来延迟加载图像,当需要它们时(使用分页将大数据集分成更小的块)。

问题是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);
    });
}

【问题讨论】:

  • 你想使用返回的images,而不是原来的items
  • return Promise.all([item.imagedata]); 似乎毫无意义。我认为您可以将其减少到return item.imagedata;

标签: arrays image promise paging es6-promise


【解决方案1】:

你是对的。承诺解析器不会在另一个对象中搜索承诺。你需要为你想要完成的整个事情返回一个承诺,尽管你可以分段完成。在这里,我添加了一个单独的函数,该函数通过链接 getItemImage 承诺结果返回一个带有 .imagedata 突变的 items[i] 的承诺。反过来,该承诺应该对所有人都可用,以便 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);
        });
}

【讨论】:

    猜你喜欢
    • 2020-04-21
    • 1970-01-01
    • 2018-05-05
    • 2017-04-04
    • 1970-01-01
    • 2018-04-17
    • 2019-09-28
    • 2022-11-26
    • 2019-05-29
    相关资源
    最近更新 更多