Skip to content

Commit 00bb76a

Browse files
committed
fix(race): concurrent next calls
not quite sure what to do about isDone
1 parent 24330c0 commit 00bb76a

File tree

1 file changed

+56
-34
lines changed

1 file changed

+56
-34
lines changed

src/execution/execute.js

Lines changed: 56 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1774,43 +1774,65 @@ export class Dispatcher {
17741774
});
17751775
}
17761776
return new Promise((resolve) => {
1777+
let resolved = false;
17771778
this._subsequentPayloads.forEach((promise) => {
1778-
promise.then(() => {
1779-
// resolve with actual promise, not resolved value of promise so we can remove it from this._subsequentPayloads
1780-
resolve({ promise });
1781-
});
1782-
});
1783-
})
1784-
.then(({ promise }) => {
1785-
this._subsequentPayloads.splice(
1786-
this._subsequentPayloads.indexOf(promise),
1787-
1,
1788-
);
1789-
return promise;
1790-
})
1791-
.then(({ value, done }) => {
1792-
if (done && this._subsequentPayloads.length === 0) {
1793-
// async iterable resolver just finished and no more pending payloads
1794-
return {
1795-
value: {
1796-
hasNext: false,
1797-
},
1798-
done: false,
1779+
promise.then((payload) => {
1780+
if (resolved) {
1781+
return;
1782+
}
1783+
1784+
resolved = true;
1785+
1786+
if (this._isDone) {
1787+
resolve({
1788+
value: {
1789+
hasNext: false,
1790+
},
1791+
done: false,
1792+
});
1793+
return;
1794+
}
1795+
1796+
if (this._subsequentPayloads.length === 0) {
1797+
// a different call to next has exhausted all payloads
1798+
resolve({ value: undefined, done: true });
1799+
return;
1800+
}
1801+
1802+
const index = this._subsequentPayloads.indexOf(promise);
1803+
1804+
if (index === -1) {
1805+
// a different call to next has consumed this payload
1806+
resolve(this._race());
1807+
return;
1808+
}
1809+
1810+
this._subsequentPayloads.splice(index, 1);
1811+
1812+
const { value, done } = payload;
1813+
1814+
if (done && this._subsequentPayloads.length === 0) {
1815+
// async iterable resolver just finished and no more pending payloads
1816+
resolve({
1817+
value: {
1818+
hasNext: false
1819+
},
1820+
done: false
1821+
});
1822+
return;
1823+
}
1824+
1825+
const returnValue: ExecutionPatchResult = {
1826+
...value,
1827+
hasNext: this._subsequentPayloads.length > 0,
17991828
};
1800-
} else if (done) {
1801-
// async iterable resolver just finished but there are pending payloads
1802-
// return the next one
1803-
return this._race();
1804-
}
1805-
const returnValue: ExecutionPatchResult = {
1806-
...value,
1807-
hasNext: this._subsequentPayloads.length > 0,
1808-
};
1809-
return {
1810-
value: returnValue,
1811-
done: false,
1812-
};
1829+
resolve({
1830+
value: returnValue,
1831+
done: false,
1832+
});
1833+
});
18131834
});
1835+
});
18141836
}
18151837

18161838
_next(): Promise<IteratorResult<AsyncExecutionResult, void>> {

0 commit comments

Comments
 (0)