簡體   English   中英

async await或Promise不返回流事件

[英]async await or Promise not returning on stream event

我有以下函數返回一個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');
  }

但是在從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 );
    }
  }

代碼到達createObjectFromconsole.log語句

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

但是沒有達到下面的console.dir聲明,因為Promise似乎沒有解決。

如果我從流處理之外的測試中調用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 } ]

我有這個包含源代碼和失敗測試的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);
    }
  }

為什么你不改變這樣的代碼:

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

天哪,這是一個屁股,因為我沒有從測試中回復承諾。 使用mocha測試promise時,需要從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 ,現在一切都很好。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM