Фильтр и карта Promise с асинхронным - PullRequest
1 голос
/ 04 марта 2020

Я получил объект обещания, который был возвращен sequelize.findAndCountAll () , и я хочу отфильтровать объект перед отображением их.

Вот мой код:

async function getCountTask(id){
    return await Tasks.count({
        where: {
            studentID: id,
            status: 'Done',
            grade: ['A', 'B']
        }
    });
}

let totalStudent = [];

await Promise.all(
    listStudent.filter(async (f) => {
        const count = await getCountTask(f.id); 
        if(count <= 3){
            return false;
        }
        return true;
    }).map(async (e) => {
        let obj = {};
            obj.id = e.id;
            obj.age = e.age;
            obj.status = 'Great';
            totalStudent.push(obj);
    })
)

Мое ожидание listStudent содержит 5 данных, но после фильтрации будет содержать только 3 данных, потому что 2 других не прошли условие. Таким образом, для окончательного результата totalStudent , содержащий 3 данных.

Но что я получил из приведенного выше кода, totalStudent имеет данные, точно такие же, как listStudent . Это потому, что сначала обрабатывается карта, а затем фильтр, поэтому карта обрабатывает данные, которые еще не были отфильтрованы.

Как сделать так, чтобы сначала она стала фильтром, а затем отобразить данные.

Заранее спасибо.

1 Ответ

2 голосов
/ 04 марта 2020

Фильтр / карта и т. Д. c, не поддерживайте async в способе их использования.

например. фильтр ожидает либо true, либо false, ваше возвращаемое обещание async функции - это всегда обещание.

await Promise.all(
    listStudent.filter(async (f) => {  <<<<---- This makes filter always return true
        const count = await getCountTask(f.id); 

Глядя на ваш код, простое решение - просто удалить фильтр и просто использовать карту ..

например ..

await Promise.all(
    listStudent.map(async (f) => {
        const count = await getCountTask(f.id); 
        if (count <= 3) return; //don't want this one.       
        let obj = {};
        obj.id = f.id;
        obj.age = f.age;
        obj.status = 'Great';
        totalStudent.push(obj);
    })
)

При просмотре Promise.all возвращает массив, вы также можете избежать использования push для totalStudent,.

например.

totalStudent = await Promise.all(
    listStudent.map(async (f) => {
        const count = await getCountTask(f.id); 
        if (count <= 3) return; //don't want this one.       
        let obj = {};
        obj.id = f.id;
        obj.age = f.age;
        obj.status = 'Great';
        return obj;
    })
)

Преимущество вышеизложенного заключается в том, что порядок возврата также сохраняется.

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