2022-03-31 17:19:08 +00:00
|
|
|
function sequential(fn) {
|
|
|
|
let sequenceState = {
|
|
|
|
running: null,
|
|
|
|
queue: []
|
|
|
|
};
|
|
|
|
|
|
|
|
function pump() {
|
|
|
|
if (sequenceState.queue.length > 0) {
|
|
|
|
const next = sequenceState.queue.shift();
|
|
|
|
run(next.args, next.resolve, next.reject);
|
|
|
|
} else {
|
|
|
|
sequenceState.running = null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function run(args, resolve, reject) {
|
|
|
|
sequenceState.running = fn(...args);
|
|
|
|
|
|
|
|
sequenceState.running.then(
|
2022-05-20 21:37:42 +00:00
|
|
|
(val) => {
|
2022-03-31 17:19:08 +00:00
|
|
|
pump();
|
|
|
|
resolve(val);
|
|
|
|
},
|
2022-05-20 21:37:42 +00:00
|
|
|
(err) => {
|
2022-03-31 17:19:08 +00:00
|
|
|
pump();
|
|
|
|
reject(err);
|
|
|
|
}
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
return (...args) => {
|
|
|
|
if (!sequenceState.running) {
|
|
|
|
return new Promise((resolve, reject) => {
|
|
|
|
return run(args, resolve, reject);
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
return new Promise((resolve, reject) => {
|
|
|
|
sequenceState.queue.push({ resolve, reject, args });
|
|
|
|
});
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
module.exports = { sequential };
|