Knex 在 for 循环中承诺
Knex promises inside for loop
我是 Node/asynchronous 编码的新手,我意识到这是一个基本问题,涉及我所缺少的一些基础知识,但对于我来说,我就是无法理解这是怎么回事上班。我正在使用 knex
为数据库播种,方法是从 CSV 中读取数据并在 for
循环中遍历行。在该循环中,我需要查询数据库中的另一个 table 和 return 关联值作为要创建的新行的一部分。
我知道 knex
return 是一个待处理的 Promise
,因此它还不能访问 returned 值。但是我似乎无法使用 async/await
或 Promise.all
获得正确的结构;我已经根据我看到的其他答案尝试了很多方法,但 none 似乎实际上很好地解释了正在发生的事情,以至于我可以成功地将它应用到我的案例中。非常感谢任何帮助。
我的 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,
...
您可以将 for 循环更改为 Array.map
并在 returned 承诺上使用 Promise.all
。
此外,seed
将 return 一个 promise,因此可以正确地调用它
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);
};
我是 Node/asynchronous 编码的新手,我意识到这是一个基本问题,涉及我所缺少的一些基础知识,但对于我来说,我就是无法理解这是怎么回事上班。我正在使用 knex
为数据库播种,方法是从 CSV 中读取数据并在 for
循环中遍历行。在该循环中,我需要查询数据库中的另一个 table 和 return 关联值作为要创建的新行的一部分。
我知道 knex
return 是一个待处理的 Promise
,因此它还不能访问 returned 值。但是我似乎无法使用 async/await
或 Promise.all
获得正确的结构;我已经根据我看到的其他答案尝试了很多方法,但 none 似乎实际上很好地解释了正在发生的事情,以至于我可以成功地将它应用到我的案例中。非常感谢任何帮助。
我的 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,
...
您可以将 for 循环更改为 Array.map
并在 returned 承诺上使用 Promise.all
。
此外,seed
将 return 一个 promise,因此可以正确地调用它
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);
};