javascript - Is it possible to reject each Promise in Promise.allSettled if it takes more than 5 seconds to resolve? - Stack Ove

I have a Promise.allSettled which i use to resolve data in the database. I have an array of Promises wh

I have a Promise.allSettled which i use to resolve data in the database. I have an array of Promises which I run through the Promise.allSettled, then I only use the resolved ones. Is it possible to set a timeout inside the Promise.allSettled, so that if a promise has still not resolved the data after 5 seconds, it should return as rejected?

My code looks like this:

await Promise.allSettled(promises)
.then(result => result.forEach(d => {
  if (d.status === 'fulfilled') {
    data.push(d.value)
  }
}));

I have a Promise.allSettled which i use to resolve data in the database. I have an array of Promises which I run through the Promise.allSettled, then I only use the resolved ones. Is it possible to set a timeout inside the Promise.allSettled, so that if a promise has still not resolved the data after 5 seconds, it should return as rejected?

My code looks like this:

await Promise.allSettled(promises)
.then(result => result.forEach(d => {
  if (d.status === 'fulfilled') {
    data.push(d.value)
  }
}));
Share Improve this question edited Nov 9, 2021 at 17:00 BML91 3,2004 gold badges37 silver badges56 bronze badges asked Dec 3, 2020 at 10:09 TheStrangerTheStranger 1,5893 gold badges25 silver badges47 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 7

You could use Promise.race on the original promise and a timeout promise that rejects, e.g.:

await Promise.allSettled(
    promises.map(promise => Promise.race([promise, rejectAfterDelay(5000)])) // **
)
.then(result => result.forEach(d => {
  if (d.status === 'fulfilled') {
    data.push(d.value)
  }
}));

...where rejectAfterDelay is something like:

const rejectAfterDelay = ms => new Promise((_, reject) => {
    setTimeout(reject, ms, new Error("timeout"));
};

Side note: You could use filter to filter out the rejected promises:

data.push(...
    await Promise.allSettled(
        promises.map(promise => Promise.race([promise, rejectAfterDelay(5000)]))
    ).then(result => result.filter(({status}) => status === "fulfilled"))
);

...although I think I'd refactor the "allSettled within timeout" part into a utility function, e.g.:

const fulfilledWithinTimeout = async (promises, timeout) => {
    promises = Array.isArray(promises) ? promises : [...promises];
    const all = await Promise.allSettled(promises.map(promise => Promise.race([promise, rejectAfterDelay(timeout)]));
    return all.filter(({status}) => status === "fulfilled");
};

then

data.push(...await fulfilledWithinTimeout(promises, 5000));

With a custom Promise class it's easy Demo:

import CPromise from "c-promise2";

CPromise.allSettled([...promises])
  .timeout(1000)
  .catch((err) => {
    console.warn(`Fail: ${err}`); // Fail: CanceledError: timeout 
  });

Such promises can handle cancellation:

import CPromise from "c-promise2";

CPromise.allSettled([
  new CPromise((resolve, reject, { onCancel }) => {
    const timer = setTimeout(resolve, 2000);
    onCancel(() => {
      clearTimeout(timer);
      console.log("Wow! timeout cleared");
    });
  })
])
  .timeout(1000)
  .catch((err) => {
    console.warn(`Fail: ${err}`);
  });

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745039991a4607753.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信