Ожидание окончания циклов с использованием await в цикле - PullRequest
0 голосов
/ 12 декабря 2018

Синхронность в циклах js все еще заставляет меня взбираться на стену.

То, что я хочу сделать, довольно просто

async doAllTheThings(data, array) {
    await array.forEach(entry => {
        let val = //some algorithm using entry keys
        let subVal = someFunc(/*more entry keys*/)
        data[entry.Namekey] = `${val}/${subVal}`;
    });
    return data; //after data is modified
}

Но я не могу сказать, действительно ли это безопасно или нет,Мне просто не нравится простой шаблон петли

for (i=0; i<arrayLength; i++) {
    //do things
    if (i === arrayLength-1) {
        return
    }
}

Я хотел лучший способ сделать это, но я не могу сказать, работает ли то, что я пытаюсь, безопасно или нет, или я просто убежалне попал в паттерн данных, который вызовет состояние гонки.

Или, может быть, я обдумываю это.Алгоритм в массиве состоит исключительно из некоторых операторов MATH и присваивания ... и небольшого вызова функции, который сам по себе также состоит исключительно из большего количества операторов MATH и присваивания.Они предположительно полностью синхронны по всем направлениям.Но циклы иногда бывают странными.

Вопрос

Можно ли таким образом использовать await вне самого цикла, чтобы вызвать код для ожидания завершения цикла??Или это единственный безопасный способ сделать это - старый способ просто проверять, где вы находитесь в цикле, и не возвращаться, пока не дойдете до конца, вручную.

1 Ответ

0 голосов
/ 12 декабря 2018

Один из лучших способов справиться с асинхронностью и циклами - это затем включить обещание и ждать Promise. Помните, что await возвращает Promise, поэтому вы можете сделать:

async function doAllTheThings(array) {
    const promises = []
    array.forEach((entry, index) => {
        promises.push(new Promise((resolve) => {
            setTimeout(() => resolve(entry + 1), 200 )
        }))
    });
    return Promise.all(promises)
}

async function main () {

    const arrayPlus1 = await doAllTheThings([1,2,3,4,5])
    console.log(arrayPlus1.join(', '))
}
main().then(() => {
    console.log('Done the async')
}).catch((err) => console.log(err))

Другой вариант -используйте генераторы , но они немного сложнее, так что если вы можете просто сохранить свои обещания и подождать, тогда это более простой подход.

По поводу вопроса в конце:

Можете ли вы использовать таким образом await вне самого цикла, чтобы вызвать код для ожидания завершения цикла?Или это единственный безопасный способ сделать это, старый способ - просто проверять, где вы находитесь в цикле, и не возвращаться, пока не дойдете до конца, вручную.

Все циклы JavaScript являются синхронными, поэтому следующийСтрока будет ожидать выполнения цикла.

Если вам нужно выполнить какой-то асинхронный код в цикле, хорошим подходом является подход, описанный выше.

Другой подход для асинхронных циклов, особенно если вам необходимо«Пауза» или получение информации извне цикла - это подход итератор / генератор.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...