NodeJS: один за другим удаляйте элементы массива, используя асинхронную операцию - PullRequest
0 голосов
/ 02 июня 2018

Мне нужно работать с каждым элементом массива, и эта операция является асинхронной.Мне нужно перейти к следующему пункту только тогда, когда первый элемент обрабатывается.Мне нужно вернуть true, если все элементы обработаны.Этот фрагмент кода сам по себе должен быть обещанием, к которому я могу подключиться.

Вот что я пытался сделать:

deleteAll(items) {
    return new Promise((resolve,reject)=>{
        items.forEach(async element => {
            await this.deleteOne(element); //Async delete operation
            items.shift();
            if(items.length-1==index)   resolve(true)
        });
    });
}

Ответы [ 3 ]

0 голосов
/ 02 июня 2018

Просто используйте старый добрый цикл:

async function deleteAll(items) {
  for(const el of items) {
    await this.deleteOne(el);
  }
  items.splice(0, items.length);
  return true;
}
0 голосов
/ 02 июня 2018

Вы должны написать что-то вроде этого:

async deleteAll(items) {
  for(let element of items) {
    await this.deleteOne(element);
  }
  items.length = 0
}

Ваш код может работать до тех пор, пока this.deleteOne успешно разрешается.Но если this.deleteOne завершится неудачно и это обещание будет отклонено, то вы получите необработанное отклонение.

И необработанное отклонение приведет к сбою всего приложения узла в будущих версиях.

Создание нового обещания (new Promise((resolve,reject)=>{ .. }) и использование другого Обещания в сочетании с только что созданным Обещанием всегда означает, что вы делаете что-то не так.

0 голосов
/ 02 июня 2018

Вам, вероятно, следует использовать Promise.all, если вы хотите проверить, все ли операции завершились, поэтому вам не нужно отслеживать все асинхронные операции самостоятельно.

async deleteAll(items) {
    await Promise.all(
       items.map(element => this.deleteOne(element))
    );
    items.splice(0, items.length); // clear items
}

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

Если вы хотите запустить его последовательно, вместо использования Promise.all выможно использовать простой for of цикл

async deleteAll(items) {
    for(const item of items)
       await this.deleteOne(item);
    // I'm done with all the items
    items.splice(0, items.length);
}

Не забудьте .catch любое отклонение:

deleteAll([1,2]).catch(err => console.log(err))

или try/catch, если оно внутри функции async,и вы используете await.

...