Це питання старіше, але я намагався зробити щось подібне. Мені потрібно тримати російських робітників. Вони структуровані в обіцянку. Мені потрібно просканувати та побачити, чи вони вирішені, відхилені чи ще тривають. Якщо рішення вирішено, мені потрібно значення, якщо його відхиляють, зробити щось, щоб виправити проблему чи очікувати на розгляд. Якщо це вирішено чи відхилено, мені потрібно почати ще одне завдання, щоб продовжувати роботу. Я не можу знайти спосіб зробити це за допомогою Promise.all або Promise.race, оскільки я продовжую працювати з обіцянками в масиві і не можу знайти спосіб їх видалення. Тож я створюю працівника, який робить трюк
Мені потрібна функція генератора обіцянок, яка повертає обіцянку, яка вирішує або відхиляє в міру необхідності. Його називають функцією, яка встановлює рамки, щоб знати, що робить обіцянка.
У коді нижче генератор просто повертає обіцянку на основі setTimeout.
Ось
//argObj should be of form
// {succeed: <true or false, nTimer: <desired time out>}
function promiseGenerator(argsObj) {
let succeed = argsObj.succeed;
let nTimer = argsObj.nTimer;
return new Promise((resolve, reject) => {
setTimeout(() => {
if (succeed) {
resolve('ok');
}
else {
reject(`fail`);
}
}, nTimer);
})
}
function doWork(generatorargs) {
let sp = { state: `pending`, value: ``, promise: "" };
let p1 = promiseGenerator(generatorargs)
.then((value) => {
sp.state = "resolved";
sp.value = value;
})
.catch((err) => {
sp.state = "rejected";
sp.value = err;
})
sp.promise = p1;
return sp;
}
doWork повертає об'єкт, що містить обіцянку та його стан та повернене значення.
У наведеному нижче коді працює цикл, який перевіряє стан та створює нових працівників, щоб тримати його на 3 працюючих.
let promiseArray = [];
promiseArray.push(doWork({ succeed: true, nTimer: 1000 }));
promiseArray.push(doWork({ succeed: true, nTimer: 500 }));
promiseArray.push(doWork({ succeed: false, nTimer: 3000 }));
function loopTimerPromise(delay) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve('ok');
}, delay)
})
}
async function looper() {
let nPromises = 3; //just for breaking loop
let nloop = 0; //just for breaking loop
let i;
//let continueLoop = true;
while (true) {
await loopTimerPromise(900); //execute loop every 900ms
nloop++;
//console.log(`promiseArray.length = ${promiseArray.length}`);
for (i = promiseArray.length; i--; i > -1) {
console.log(`index ${i} state: ${promiseArray[i].state}`);
switch (promiseArray[i].state) {
case "pending":
break;
case "resolved":
nPromises++;
promiseArray.splice(i, 1);
promiseArray.push(doWork({ succeed: true, nTimer: 1000 }));
break;
case "rejected":
//take recovery action
nPromises++;
promiseArray.splice(i, 1);
promiseArray.push(doWork({ succeed: false, nTimer: 500 }));
break;
default:
console.log(`error bad state in i=${i} state:${promiseArray[i].state} `)
break;
}
}
console.log(``);
if (nloop > 10 || nPromises > 10) {
//should do a Promise.all on remaining promises to clean them up but not for test
break;
}
}
}
looper();
Тестовано у node.js
До речі, не в цій відповіді так багато, але в інших на подібні теми, я ненавиджу це, коли хтось каже "ти не розумієш" або "це не так, як це працює". Я загалом припускаю, що запитуючий знає, чого вони хочуть. Запропонувати кращий спосіб - це чудово. Терпляче пояснення того, як обіцяють роботу, також було б добре.