Это старый вопрос, но я пытался сделать что-то подобное. Мне нужно, чтобы работники продолжали работать. Они структурированы в обещании. Мне нужно отсканировать и посмотреть, были ли они решены, отклонены или все еще ожидают. Если решено, мне нужно значение, если отклонено, сделать что-то, чтобы исправить проблему или в ожидании. Если решено или отклонено, мне нужно запустить другое задание, чтобы продолжать работу. Я не могу найти способ сделать это с 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
Кстати, не в этом ответе так много, но в других на подобные темы, я НЕНАВИЖУ это, когда кто-то говорит «ты не понимаешь» или «это не так работает», я обычно предполагаю, что спрашивающий знает, чего они хотят. Предлагать лучший способ - это здорово. Терпеливое объяснение того, как работают обещания, также было бы хорошо.