如何为Promise.all及map中的GET请求添加间隔超时?
Got it, let's break down why your current setup is running all delays first then all requests, and how to fix it to get the exact flow you want: (optional initial delay) → request 1 → delay → request 2 → delay → request 3...
The Root Problem
Your original code uses Promise.all, which triggers all promises in parallel as soon as the map runs. That means every timer and every request starts at the exact same time—so all timers finish around the same time, then all requests complete shortly after. To get sequential execution, we need to chain the operations so each one waits for the previous to finish.
The Solution: Use Array.reduce to Build a Promise Chain
We'll use Array.reduce to create a sequential chain of promises, where each step waits for the prior one to complete before running the next delay + request (or just the first request if you skip the initial delay).
Here's the revised code:
// Keep your existing timer function—it's perfect const timer = ms => new Promise(res => setTimeout(res, ms)); function promiseGetInformationFromMultipleUrls(parts, delayMs = 1000) { // Use reduce to build a sequential promise chain return parts.reduce((promiseChain, part, index) => { return promiseChain.then(accumulatedResults => { // Skip the delay before the first request if (index > 0) { // Wait for the delay first, then run the request return timer(delayMs).then(() => { return fetchPartData(part).then(data => { accumulatedResults.push(data); return accumulatedResults; }); }); } else { // First request runs immediately, no prior delay return fetchPartData(part).then(data => [data]); } }); }, Promise.resolve([])); // Start with an empty resolved promise to kick off the chain } // Extract the request logic into a reusable helper function function fetchPartData(part) { return request({ 'url': `https://example.com/${part}`, 'json': true }) .then(partData => { console.log("Part data was fetched: " + part); return partData.result; }) .catch(err => { console.error("Error during fetching data from part: " + part + ", error code: " + err.statusCode); // Return a default value (like null) to keep the chain going even if a request fails return null; }); }
How This Works
Array.reduceiterates over eachpartin order, building a chain of promises. Each step only runs after the previous one resolves.- The first request runs right away (no delay before it, as you requested).
- For every subsequent request: we first wait for the specified delay, then fire off the request, then add the result to our accumulated array.
- The final returned promise will resolve to an array of all results (matching the format of your original
Promise.allimplementation).
Optional: Add an Initial Delay
If you later decide you want a delay before the first request too, just remove the index > 0 check. All steps will then follow delay → request:
// Revised reduce logic for initial delay + all subsequent delays return promiseChain.then(accumulatedResults => { return timer(delayMs).then(() => { return fetchPartData(part).then(data => { accumulatedResults.push(data); return accumulatedResults; }); }); });
内容的提问来源于stack exchange,提问作者profiler

