我有以下函数返回一个Promise,其中函数参数是一个异步函数:
createObjectFrom(record) {
const self = this;
return new Promise(async (resolve, reject) => {
let obj = {};
for(let i = 0, l = self.opts.transformers.length; i < l; i++) {
let transformer = self.opts.transformers[i];
const headerIndex = findIndex(self.headers, (header) => {
return header === transformer.column;
});
let csvValue = record[headerIndex];
const lookUp = transformer.options.lookUp;
const whereClause = {};
whereClause[lookUp.column] = csvValue;
console.log('before await');
const result = await self.knex(lookUp.table).where(whereClause).select(lookUp.scalar);
console.dir(result);
obj[transformer.field] = result[0][lookUp.scalar];
}
return resolve(obj);
});
}
如果我在测试中调用这样的函数,它都会正确执行:
it('creates the transformed object', async () => {
const csvRecord = ['PREMIER', '07/11/1998', manager, 'Liverpool', 'Wimbledon', 0, 1, 'A', 0, 1, 'A'];
const record = await transformer.createObjectFrom(csvRecord);
expect(record.division).to.equal('PREMIER');
}
但是在从readable创建的流中引发的csv-parse事件期间调用createObjectFrom
函数时:
onReadable() {
let record = this.parser.read();
if (record === null) {
return;
}
if (this.parser.count <= 1) {
this.headers = record;
} else {
const recordPromises = this.createObjectFrom(record);
this.recordPromises.push( newRecord );
}
}
代码转到console.log
createObjectFrom
语句
console.log('before here');
const result = await self.knex(lookUp.table).where(whereClause).select(lookUp.scalar);
console.dir(result);
但由于Promise似乎无法解决,因此无法进入下面的console.dir
声明。
如果我从流处理之外的测试中调用createObjectFrom
,那么它会正确解析。
我也试过重构异步等待退出一个承诺,但它仍然破产。
If I console.dir the promises on the [end][3] event of the stream they look like this:
[ Promise {
_bitField: 0,
_fulfillmentHandler0: undefined,
_rejectionHandler0: undefined,
_promise0: undefined,
_receiver0: undefined },
Promise {
_bitField: 0,
_fulfillmentHandler0: undefined,
_rejectionHandler0: undefined,
_promise0: undefined,
_receiver0: undefined } ]
我有this repo,它有源代码和失败的测试。
我对发生的事情感到困惑。
以下测试也通过,因此肯定与流有关:
it('creates the transformed object', async () => {
const csvRecords = [
['PREMIER', '07/11/1998', manager, 'Liverpool', 'Wimbledon', 0, 1, 'A', 0, 1, 'A'],
['PREMIER', '11/11/1998', manager, 'QPR', 'Sunderland',3,3, 'Sunderland',0,0,'Sunderland'],
['PREMIER', '14/11/1998', manager, 'Southampton', 'Liverpool', 3, 3, 'D', 0, 0, 'D']
];
for(var i = 0, l = csvRecords.length; i < l; i++) {
const csvRecord = csvRecords[i];
const record = await transformer.createObjectFrom(csvRecord);
expect(record.division).to.equal('PREMIER');
expect(record.manager_id).to.equal(manager_id);
}
}
答案 0 :(得分:2)
为什么你不改变这样的代码:
createObjectFrom: async (record) => {
const self = this;
// return new Promise(async (resolve, reject) => {
let obj = {};
for(let i = 0, l = self.opts.transformers.length; i < l; i++) {
let transformer = self.opts.transformers[i];
const headerIndex = findIndex(self.headers, (header) => {
return header === transformer.column;
});
let csvValue = record[headerIndex];
const lookUp = transformer.options.lookUp;
const whereClause = {};
whereClause[lookUp.column] = csvValue;
console.log('before await');
const result = await self.knex(lookUp.table).where(whereClause).select(lookUp.scalar);
console.dir(result);
obj[transformer.field] = result[0][lookUp.scalar];
}
return obj;
// return resolve(obj);
// });
}
答案 1 :(得分:2)
it
函数返回promise。如果你这样做,一切正常。太傻了!
所以,如果我将测试更改为:
describe('transformer', () => {
it('transforms the data and imports the csv file', () => {
const ignoreIf = (data) => data[3] !== 'Liverpool' && data[4] !== 'Liverpool';
const opts = { table: 'results', file: __dirname + '/fixtures/test.csv', encoding: 'utf8', transformers, ignoreIf: ignoreIf };
const f = seeder(opts)(knex, Promise);
return f.then((results) => {
console.dir(results);
});
});
我return f
现在一切都很好。