【问题标题】:Cancelling Bluebirds Promise.all when fetched x items获取 x 项时取消 Bluebirds Promise.all
【发布时间】:2018-02-01 08:31:43
【问题描述】:

我正在尝试获取 X 数量的库存商品,一旦我拥有它们,我就不想再获取它们了。到目前为止,这是我的代码:

const numberOfInstockItemsToShow = 10;

let inStockCount = 0;

let cancellablePromise;

const promises = data.map((item) => {
    return fetch(url, options).then((res) => {
        if (res.ok) {
            return res.json()
        }
    }).then((d) => {
        inStockCount++;

        if (inStockCount >= numberOfInstockItemsToShow) {
            cancellablePromise.cancel();
        }
        return d;
    });
});

cancellablePromise = Promise.all(promises).then((d) => {
  console.log("all the files were created:", d);
});

我在配置中将取消设置为 true,所以我认为这与我的狡猾代码有关。

感谢任何帮助:)

【问题讨论】:

  • 您希望在取消承诺后会发生什么?您观察到的情况与此不同?根据 Bluebird 文档,取消承诺的作用是防止调用其 .then().catch() 处理程序。它实际上并没有取消任何底层异步操作。对于Promise.all(),它不会影响它正在监视的promise,只会影响Promise.all() 返回的主promise 的.then().catch() 处理程序。
  • 因此,如果您希望在找到足够高的inStockCount 后中止任何进一步的fetch() 调用,那么.cancel() 根本不会帮助您.所有其他 ajax 调用都已发送,并且在主承诺上使用 .cancel() 根本不会影响它们。所以,所发生的一切就是你不会从Promise.all() 中得到任何结果,因为你取消了它。
  • 好的,这很有道理。不是我希望的答案,但可以节省我在这种方法上浪费的更多时间。谢谢或您的帮助!
  • 您是否要对fetch() 调用进行排序,以便进行一次调用,检查其结果,然后决定是否进行下一次调用?
  • 这就是我目前正在做的事情,并且正在为此使用递归函数。但是我想异步运行它们,否则一次运行它有点慢。

标签: javascript promise fetch bluebird cancellation


【解决方案1】:

您可以使用Promise.some([...], count)。第一个参数是一个数组,第二个参数是许多已解决的 Promise,它们被视为已实现。 Reference

const numberOfInstockItemsToShow = 10;

const promises = data.map((item) => {
    return fetch(url, options).then((res) => {
        if (res.ok) {
            return res.json()
        }
    });
});

Promise.some(promises, numberOfInstockItemsToShow).then((d) => {
  console.log("all the files were created:", d);
});

请注意,在到达count 后,这不会取消任何进一步的承诺。只要解决了所需数量的 Promise,这将简单地实现。

【讨论】:

  • 感谢您的回答@abskmj,但就像您提到的那样,它不会取消剩余的提取。这一半解决了我的问题,但没有完全解决。
猜你喜欢
  • 2023-04-01
  • 2018-06-26
  • 2017-05-21
  • 2020-03-27
  • 2022-08-17
  • 2017-09-19
  • 2019-02-13
  • 1970-01-01
  • 2015-10-21
相关资源
最近更新 更多