我正在使用Promise.allSettled对Github API的几百个请求进行多次获取。我被阻塞了,因为它们都被同时调用,所以我想在每个请求之间添加5毫秒的延迟。这可以使用Promise.allSettled吗?
zbsbpyhn1#
allSettled既不会帮助你,也不会阻碍你;它在时间方面没有任何逻辑,除了等待promise解决。它将由你来创建你的promise,以便它们具有你想要的延迟。举例来说:
allSettled
const delay = (milliseconds) => new Promise(resolve => setTimeout(resolve, milliseconds); const urls = ['www.foo.com/whatever', /* etc for a few hundred urls */]; const promises = urls.map((url, index) => { return delay(index * 5) .then(() => fetch(url)) }) Promise.allSettled(promises) .then(results => { // do whatever with the results });
字符串
o75abkj42#
可能你需要的是并发限制,而不是延迟。
const urls = [ "https://run.mocky.io/v3/40594989-00c2-4798-94da-c4a9ab251558?mocky-delay=3s&foo1", "https://run.mocky.io/v3/40594989-00c2-4798-94da-c4a9ab251558?mocky-delay=3s&foo2", "https://run.mocky.io/v3/40594989-00c2-4798-94da-c4a9ab251558?mocky-delay=3s&foo3", "https://run.mocky.io/v3/40594989-00c2-4798-94da-c4a9ab251558?mocky-delay=3s&foo4", "https://run.mocky.io/v3/40594989-00c2-4798-94da-c4a9ab251558?mocky-delay=3s&foo5", "https://run.mocky.io/v3/40594989-00c2-4798-94da-c4a9ab251558?mocky-delay=3s&foo6", "https://run.mocky.io/v3/40594989-00c2-4798-94da-c4a9ab251558?mocky-delay=3s&foo7" ]; function fetchBottleneck(concurrency = 1) { const queue = []; let pending = 0; return async (...args) => { if (pending === concurrency) { await new Promise((resolve) => queue.push(resolve)); } pending++; return fetch(...args).then((value) => { pending--; queue.length && queue.shift()(); return value; }); }; } // Use fetch queue (async () => { const fetchInQueue = fetchBottleneck(3); //No matter how many times you call the 'fetchInQueue' method, you get a maximum of 3 pending requests at the same time. const results = await Promise.all( urls.map(async (url) => { try { const response = await fetchInQueue(url); console.log(`Got response for ${url}`); return { status: "fulfilled", value: await response.json() }; } catch (reason) { return { status: "rejected", reason }; } }) ); console.log("Done:", JSON.stringify(results)); })();
字符串更好的解决方案是使用多个第三方库提供的并发限制(例如http://bluebirdjs.com/docs/api/promise.map.html)Live browser example的
import CPromise from "c-promise2"; CPromise.allSettled( [ "https://run.mocky.io/v3/40594989-00c2-4798-94da-c4a9ab251558?mocky-delay=3s&foo1", "https://run.mocky.io/v3/40594989-00c2-4798-94da-c4a9ab251558?mocky-delay=4s&foo2", "https://run.mocky.io/v3/40594989-00c2-4798-94da-c4a9ab251558?mocky-delay=2s&foo3", "https://run.mocky.io/v3/40594989-00c2-4798-94da-c4a9ab251558?mocky-delay=3s&foo4", "https://run.mocky.io/v3/40594989-00c2-4798-94da-c4a9ab251558?mocky-delay=4s&foo5", "https://fake.url.to.test/", "https://run.mocky.io/v3/40594989-00c2-4798-94da-c4a9ab251558?mocky-delay=3s&foo6", "https://run.mocky.io/v3/40594989-00c2-4798-94da-c4a9ab251558?mocky-delay=3s&foo7" ], { mapper: (url) => { console.log(`request [${url}]`); return fetch(url).then((response) => response.json()); }, concurrency: 2 } ).then((results) => { console.log(`Done: `, JSON.stringify(results)); });
型
ssgvzors3#
这个版本的Promise.allSettled使用了上面定义的delay方法,但是在调用之间添加了一个随机延迟,它可以选择过滤fulfilled或rejected Promise状态:
Promise.allSettled
delay
fulfilled
rejected
function allSettledDelayed(promises = [], milliseconds = 100, status = '') { return new Promise(async(resolve, reject) => { const delay = (milliseconds) => new Promise(resolve => setTimeout(resolve, milliseconds)); try { let randomInt = (min, max) => Math.floor(Math.random() * (max - min + 1)) + min; promises = promises.map((promise, index) => delay(randomInt(0, (index+1) * milliseconds)).then(() => promise)); var responses = await Promise.allSettled(promises); if (status == "fulfilled" || status == "rejected") responses = responses.filter(p => p.status === status).map(p => p.value); return resolve(responses); } catch (error) { return reject(error); } }); } //allSettledDelayed (async() => { var urls = Array(10).fill().map((v, i) => `https://httpbin.org/response-headers?key=${i}`); const promises = urls.map(url => fetch(url).then((response) => response.status)) var res = await allSettledDelayed(promises, 300, '') console.log(res) })();
3条答案
按热度按时间zbsbpyhn1#
allSettled
既不会帮助你,也不会阻碍你;它在时间方面没有任何逻辑,除了等待promise解决。它将由你来创建你的promise,以便它们具有你想要的延迟。举例来说:
字符串
o75abkj42#
可能你需要的是并发限制,而不是延迟。
字符串
更好的解决方案是使用多个第三方库提供的并发限制(例如http://bluebirdjs.com/docs/api/promise.map.html)
Live browser example的
型
ssgvzors3#
这个版本的
Promise.allSettled
使用了上面定义的delay
方法,但是在调用之间添加了一个随机延迟,它可以选择过滤fulfilled
或rejected
Promise状态:字符串