Asynchronous wait or promise not to return an event in the stream

I have the following function that returns Promise, where the function argument is an asynchronous function:

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

If I call a function like this from the test, everything will execute correctly:

  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'); } 

But when the createObjectFrom function is createObjectFrom during the readable event, which is created from the stream created from csv-parse :

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

This code gets into the console.log statement below in createObjectFrom

  console.log('before here'); const result = await self.knex(lookUp.table).where(whereClause).select(lookUp.scalar); console.dir(result); 

But it does not fit the console.dir statement below, since Promise does not seem to allow.

If I call createObjectFrom from the test outside of the processing stream, it will be resolved correctly.

I also tried async refactoring to wait on this to just return the promise, but it still broke.

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

I have this repo that has source code and a failed test.

I am puzzled by what is happening.

The following test also passes, so it is definitely thread related:

  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); } } 
+5
source share
2 answers

why don't you change your code as follows:

 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); // }); } 
+2
source

OMG, what an ass, it was because I did not return a promise from the test. When testing promises with a mocha, you need to return a promise from the it function. If you do, everything will work. What a fool!

So, if I change the test to this:

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

I return f , and now everything is fine.

+2
source

All Articles