【问题标题】:Node js getting blank obj even after pushing data即使在推送数据后,节点 js 也会得到空白 obj
【发布时间】:2020-04-16 01:54:24
【问题描述】:

我在这里尝试将数据推送到我的数组中,但它总是为空。

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) 中我没有得到任何数据,但是当我控制台时,我正在从 db 中获取数据。

【问题讨论】:

  • 快速猜测,可能是因为cb(null, obj)执行得更早,所以在你将数据推送到数组之前。由于异步操作?

标签: javascript node.js knex.js async.js


【解决方案1】:

因为你的函数是异步的。这意味着当你的回调cb(null, obj) 被调用时,数据还没有出现。您希望在执行每个异步函数后调用回调。

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
    })
}]

【讨论】:

  • 我在异步每个块之后调用 cb。
  • 我已经编辑了我的答案。检查回调函数的位置作为async.each函数的第三个参数。
  • 仍然是第一个被调用的。
  • 我已经编辑了完整的代码。不明白的请仔细查看async.each
【解决方案2】:

问题是你在另一个异步调用(async.each)中有一个异步调用(knex),cb(null, obj) 没有等待前一个异步任务完成,因此更早执行。此外,如果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 function (result, cb)...前面的async关键字和await Promises.all(promises);前面的await

希望对你有帮助

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-08-24
    • 1970-01-01
    • 1970-01-01
    • 2021-11-15
    • 1970-01-01
    • 2018-03-13
    • 1970-01-01
    • 2022-12-12
    相关资源
    最近更新 更多