Node js получение пустого объекта даже после отправки данных - PullRequest
1 голос
/ 15 апреля 2020

Здесь я пытаюсь поместить sh данные в мой массив, но он всегда пуст.

read_file: ['pass_fileData', function (result, cb) {
    let obj = [];
    async.each(result.pass_fileData, function (item) {
        knex
        .select('xxxxx')
        .from('xxxx')
        .innerJoin('xxxx', 'xxxx', 'xxx')
        .where('xxxxx', '=', item)
        .then(function (data) {
            obj.push(data) // here I am pushing data to array
        })
        .catch(function (err) {
            cb(err);
        })
    })
    cb(null, obj)
}]

В CB(null, obj) Я не получаю никаких данных, но когда я утешаю, я получаю данные из БД.

Ответы [ 2 ]

2 голосов
/ 15 апреля 2020

Потому что ваша функция асинхронная. Это означает, что когда ваш обратный вызов cb(null, obj) вызван, данных еще нет. Вы хотите вызывать обратный вызов после выполнения каждой функции asyn c.

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

Ваш код должен выглядеть следующим образом:

read_file: ['pass_fileData', function (result, cb) {
    let obj = [];
    async.each(result.pass_fileData, function (item, callback) {
        knex
        .select('xxxxx')
        .from('xxxx')
        .innerJoin('xxxx', 'xxxx', 'xxx')
        .where('xxxxx', '=', item)
        .then(function (data) {
            obj.push(data) // here I am pushing data to array
            callback() // Iteratee callback
        })
        .catch(function (err) {
            callback(err); // Iteratee callback
        })
    }, function (err) { // end callback
      cb(err, obj) // Your callback that takes the obj
    })
}]
1 голос
/ 15 апреля 2020

Проблема в том, что у вас есть асинхронный вызов (knex) внутри другого асинхронного вызова (async.each), cb(null, obj) не ожидает, пока предыдущая асинхронная задача c завершит sh, таким образом, выполняясь раньше. Кроме того, если async.each не является требованием, вы можете от него избавиться и просто использовать Promises . Просто выполните итерацию по result.pass_fileData, сохраните все обещания knex в массиве, затем используйте Promise.all с массивом, и это сделает работу.

read_file: ['pass_fileData', function (result, cb) {
    const obj = [];
    const promises = [];

    // asuming "result.pass_fileData" is an array
    result.pass_fileData.forEach(function (item) {
        const singlePromise = knex
        .select('xxxxx')
        .from('xxxx')
        .innerJoin('xxxx', 'xxxx', 'xxx')
        .where('xxxxx', '=', item)
        .then(function (data) {
            obj.push(data) // here I am pushing data to array
        })
        .catch(function (err) {
            cb(err);
        });

        promises.push(singlePromise); // store all the promises in an array
    });

    Promises.all(promises).then(function() {
      cb(null, obj);
    });

}]

Если вы можете использовать async/await ( почему нет?) Вы можете немного изменить код

read_file: ['pass_fileData', async function (result, cb) {
    const obj = [];
    const promises = [];

    // asuming "result.pass_fileData" is an array
    result.pass_fileData.forEach(function (item) {
        const singlePromise = knex
        .select('xxxxx')
        .from('xxxx')
        .innerJoin('xxxx', 'xxxx', 'xxx')
        .where('xxxxx', '=', item)
        .then(function (data) {
            obj.push(data) // here I am pushing data to array
        })
        .catch(function (err) {
            cb(err);
        });

        promises.push(singlePromise); // store all the promises in an array
    });

    await Promises.all(promises);

    cb(null, obj);
}]

Обратите внимание на ключевое слово async перед async function (result, cb)... и await перед await Promises.all(promises);

Надеюсь помогает * * 1023

...