【问题标题】:Knex promises inside for loopKnex 在 for 循环中承诺
【发布时间】:2020-05-14 15:26:05
【问题描述】:

我是 Node/异步编码的新手,我意识到这是一个基本问题,它说明了我缺少的一些基础知识,但对于我的生活,我就是无法理解它应该如何工作。我正在使用knex 为数据库播种,方法是从CSV 读取数据并在for 循环中遍历行。在该循环中,我需要查询数据库中的另一个表并返回一个关联值作为要创建的新行的一部分。

我知道knex 返回一个待处理的Promise,所以它还不能访问返回的值。但我似乎无法用async/awaitPromise.all 获得正确的结构;我已经根据我看到的其他答案尝试了很多方法,但似乎没有一个能真正解释发生的事情足以让我可以成功地将它应用到我的案例中。非常感谢任何帮助。

我的seed 文件目前如下所示:

exports.seed = function(knex) {
  const fs = require('fs');

  function createImage(row, event_id) {
    return {
      name: row[1],
      event_id: event_id
    }
  };

  function get_event_id(loc) {
    knex('events')
      .where({location: loc})
      .first()
      .then(result => {console.log(result)});    // <-- this never executes
  };

    let images = [];

    const file = fs.readFileSync('./data.csv');
    const lines = file.toString().replace(/[\r]/g, '').split('\n');

    for (i=1; i<lines.length; i++) {
      var row = lines[i].split(',');

      var event_id = (async function () { return await get_event_id(row[0]) }) ();

      images.push(createImage(row, event_id));

      };

    console.log(images);
    // Inserts seed entries
    // return knex('table_name').insert(images);

};

输出: [ { name: '003.jpg', event_id: undefined } ]

我的data.csv 的结构如下:

Location,Name
Amsterdam,003.jpg,
...

【问题讨论】:

  • @AZ_ 如果是这样,您可能需要再为我拼写一下(抱歉)。我认为我所缺少的与Promises 本身有关,而不是关闭本身。例如,运行lines.slice(0,2).forEach(function(line) { knex('events') .where({location: line[0].split(',')[0]}) .first() .then(result =&gt; {console.log(result)}); }) 似乎没有帮助(console.log 仍然没有执行)。但也许我错过了你的意思。

标签: javascript node.js asynchronous io knex.js


【解决方案1】:

您可以将 for 循环更改为 Array.map 并在返回的 Promise 上使用 Promise.all

另外,seed 将返回一个承诺,因此请正确调用它

exports.seed = async function (knex) {
    const fs = require('fs');

    function createImage(row, event_id) {
        return {
            name: row[1],
            event_id: event_id
        }
    };

    function get_event_id(loc) {
        return knex('events')
            .where({ location: loc })
            .first()
            .then(result => { console.log(result); return result });    // <-- this never executes
    };


    const file = fs.readFileSync('./data.csv');
    const lines = file.toString().replace(/[\r]/g, '').split('\n');

    let promises = lines.map(async (line) => {
        let [row] = line.split(',');
        let event_id = await get_event_id(row)
        return createImage(row, event_id)
    });

    let images = await Promise.all(promises);

    console.log(images);
    // Inserts seed entries
    // return knex('table_name').insert(images);
}; 

【讨论】:

  • 这似乎(咳咳)很有希望,但我无法让lines.map() 工作——它说它不是一个函数,尽管Array.isArray(lines) 返回true。有什么想法吗?
  • Error: Error while executing _filename_ seed: lines.map(...) is not a function at Promise.resolve.then.then.catch _path_/node_modules/knex/lib/seed/Seeder.js:146:25) TypeError: lines.map(...) is not a function at Object.exports.seed (_path_/db/seeds/addMimo.js:37:7) at Promise.resolve.then (_path_/node_modules/knex/lib/seed/Seeder.js:143:26)
  • 我的错字已修复。
  • 嗯,它现在可以运行了,但是最后打印的 images 数组显示了所有未定义的值。
  • 更新迭代以调用createImage,并检查您是否收到event_id
猜你喜欢
  • 2023-03-17
  • 2015-12-18
  • 1970-01-01
  • 1970-01-01
  • 2016-10-11
  • 1970-01-01
  • 2017-12-10
  • 2016-12-08
相关资源
最近更新 更多