#node.js #asynchronous #promise
#node.js #асинхронный #обещание
Вопрос:
У меня есть массив, подобный [1,2,3,4,5,6,7,8,9,10]. Я хочу запустить forEach этого массива, у каждого элемента есть тайм-аут 1 с, и если текущий элемент соответствует условию, то прервите foreach. я нашел код, который работал только с out async:
var BreakException = {};
try {
[1,2,3,4,5,6,7,8,9,10].forEach(function(el) {
console.log(el);
if (el === 6) throw BreakException;
});
} catch (e) {
if (e !== BreakException) throw e;
}
Но когда я использую async, он запускает все элементы:
var BreakException = {};
let list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
var realtimePromise = new Promise((resolve, reject) => {
list.every(async(item, pKey) => {
await setTimeout(function() {
try {
console.log(item);
if (item === 6) throw BreakException;
} catch (e) {
if (e !== BreakException) throw e;
}
}, 2000 * pKey);
});
});
realtimePromise.then(() => {
console.log('------- End loop -------');
});
У кого-нибудь есть решение этой проблемы?
Комментарии:
1. Вы действительно не должны использовать исключения в качестве потока управления. Я предлагаю использовать обычный цикл, из которого вы можете легко выйти.
2. Кроме того,
setTimeout
не возвращает обещание, поэтомуawait setTimeout
не имеет смысла.
Ответ №1:
Вам было бы лучше использовать рекурсивную функцию, подобную этой, поскольку выход из forEach
цикла с ошибкой не является хорошей практикой:
const list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const realtimePromise = (index = 0) => {
return new Promise((resolve, reject) => {
if (index > list.length - 1) reject(new Error('Item not in list'));
const currentItem = list[index];
console.log(currentItem);
if (currentItem === 6) resolve(currentItem);
else setTimeout(() => {
resolve(realtimePromise( index));
}, 2000);
});
}
realtimePromise().then(() => {
console.log('------- End loop -------');
});