Может ли цикл nodejs быть асинхронным? - PullRequest
0 голосов
/ 27 мая 2018

Пока работает этот код, я ничего не могу сделать.Есть ли асинхронный путь для циклов?

// This object is very large
var listOfUsers = {};

for(var key in listOfUsers){
  delete listOfUsers[key]  
}

1 Ответ

0 голосов
/ 27 мая 2018

Есть ли асинхронный путь для циклов?

Нет.Поскольку delete listOfUsers[key] сама по себе является синхронной операцией, то во время выполнения этого цикла больше ничего нельзя делать.Интерпретатор JS занят выполнением цикла и выполнением этой операции delete.Поскольку Javascript в node.js является однопоточным, то есть одновременно выполняется только один набор Javascript.Вы не можете выполнить что-либо еще, пока цикл не будет завершен.

Мне приходит в голову, что, если вы просто пытаетесь вернуть listOfUsers к пустому объекту, и никто больше не держит ссылку на исходный объектВы могли бы заменить существующий цикл следующим образом:

listOfUsers = {};

, хотя это было бы намного быстрее.Тогда старый объект (и его свойства) будут собирать мусор.


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

Например, вы можете сделать что-то вроде этого:

// remove all users, chunked to 100 at a time
// allowing the event loop to run between chunks
function removeUsers() {
    const chunkSize = 100;
    let usersToDelete = Object.keys(listOfUsers).slice(chunkSize);
    if (!usersToDelete.length) {
        // everything deleted, no more work to do
        return;
    } else {
    for (let key of usersToDelete) {
        delete listOfUsers[key];
    }
    // delete some more after other things get a chance to run in the event loop
    setTimeout(removeUsers, 20);
}

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

...