【问题标题】:Make sure promise resolved inside transformFunction确保 promise 在 transformFunction 中得到解决
【发布时间】:2017-12-01 12:36:39
【问题描述】:

我正在学习through2sequelize

我的代码:

  return Doc.createReadStream({
    where: { /*...*/ },
    include: [
      {
        /*...*/
      },
    ],
  })
  .pipe(through({ objectMode: true }, (doc, enc, cb) => {
    Comment.findOne(null, { where: { onId: doc.id } }).then((com) => { /* sequelize: findOne*/
      com.destroy(); /* sequelize instance destroy: http://docs.sequelizejs.com/manual/tutorial/instances.html#destroying-deleting-persistent-instances */
      cb();
    });
  }))
  .on('finish', () => {
    console.log('FINISHED');
  })
  .on('error', err => console.log('ERR', err));

我试图清楚地表达我的问题。 DocComment 是续集模型。我想使用流从数据库中一个一个地读取 Doc 实例,并删除每个 Doc 实例上的 cmets。 Comment.findOnecom.destroy() 都将返回承诺。我想为每个doc 解决承诺,然后调用cb()。但是我上面的代码不能工作,在com被销毁之前,代码已经运行完毕了。

如何解决?谢谢

我把上面这段代码包装在mocha测试中,比如

it('should be found by readstream', function _testStream(){
  /* wrap the first piece of codes here*/
});

但在流读完之前,测试已经存在。

【问题讨论】:

    标签: node.js sequelize.js node-streams through2


    【解决方案1】:

    您可以通过返回承诺并使用另一个.then 来等待另一个承诺。

    在运行.destroy() 之前,您可能还需要检查com 结果是否为null

      .pipe(through({ objectMode: true }, (doc, enc, cb) => {
        Comment.findOne(null, { where: { onId: doc.id } })
          .then(com => com.destroy())
          .then(()=> cb())
          .catch(cb)
      }))
    

    然后在 mocha 中运行测试时,您需要通过在测试函数签名中添加 done 并在完成或错误时调用 done() 来等待异步流。

    it('should be found by readstream', function _testStream(done){
      ...
      .on('finish', () => done())
      .on('error', done)
    })
    

    【讨论】:

    • 太棒了。但现在,我不能使用await
    • 我尝试了第一个解决方案,但同样,在流完成读取之前,测试已经存在。我认为问题在于整个承诺链是异步的..
    • 啊,是的。您需要将done 与 mocha 和流一起使用来表示异步测试的结束...我将在中添加
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-10-31
    • 1970-01-01
    • 1970-01-01
    • 2023-03-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多