Skip to content

Commit 9fdb2b9

Browse files
create spawnInto helper to avoid .then
1 parent d9b204a commit 9fdb2b9

File tree

1 file changed

+34
-31
lines changed

1 file changed

+34
-31
lines changed

index.js

Lines changed: 34 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -205,47 +205,50 @@ export function pMapIterable(
205205
let isDone = false;
206206
let index = 0;
207207

208-
function trySpawn() {
209-
if (isDone || !(runningMappersCount < concurrency && promises.length < backpressure)) {
210-
return;
211-
}
212-
213-
const promise = (async () => {
208+
const spawnInto = async deferredPromise => {
209+
let result;
210+
try {
214211
const {done, value} = await iterator.next();
215212

216213
if (done) {
217-
return {done: true};
218-
}
214+
result = {done: true};
215+
} else {
216+
runningMappersCount++;
217+
218+
// Spawn if still below concurrency and backpressure limit
219+
trySpawn();
219220

220-
runningMappersCount++;
221+
const returnValue = await mapper(await value, index++);
221222

222-
// Spawn if still below concurrency and backpressure limit
223-
trySpawn();
223+
runningMappersCount--;
224224

225-
const returnValue = await mapper(await value, index++);
225+
if (returnValue === pMapSkip) {
226+
popSpecificPromise(deferredPromise.promise);
227+
}
226228

227-
runningMappersCount--;
229+
// Spawn if still below backpressure limit and just dropped below concurrency limit
230+
trySpawn();
228231

229-
if (returnValue === pMapSkip) {
230-
popSpecificPromise(promise);
232+
result = {done: false, value: returnValue};
231233
}
234+
} catch (error) {
235+
isDone = true;
236+
result = {error};
237+
}
238+
239+
deferredPromise.resolve({promise: deferredPromise.promise, result});
240+
somePromiseHasSettled?.resolve(deferredPromise.promise);
241+
};
242+
243+
function trySpawn() {
244+
if (isDone || !(runningMappersCount < concurrency && promises.length < backpressure)) {
245+
return;
246+
}
232247

233-
// Spawn if still below backpressure limit and just dropped below concurrency limit
234-
trySpawn();
235-
236-
return {done: false, value: returnValue};
237-
})()
238-
.catch(error => {
239-
isDone = true;
240-
return {error};
241-
})
242-
// Include a reference to the promise so `popRandomPromise` can find `indexOf`
243-
.then(result => ({result, promise}));
244-
245-
promises.push(promise);
246-
promise.then(p => {
247-
somePromiseHasSettled.resolve(p);
248-
});
248+
// Create a deferred promise so `spawnInto` can `popSpecificPromise` what we push into `promises` (`indexOf` needs object reference)
249+
const deferredPromise = pDefer();
250+
promises.push(deferredPromise.promise);
251+
spawnInto(deferredPromise);
249252
}
250253

251254
trySpawn();

0 commit comments

Comments
 (0)