【问题标题】:Node Promise not worth waiting forNode Promise 不值得等待
【发布时间】:2020-12-07 21:14:48
【问题描述】:

所以尽我所能了解 node.js 中的流、promise 和异步函数。我似乎从来没有做对。我有几个非常相似的用例(而且看起来很标准)。像这样的:

  1. 我有一个获取一些数据的流
  2. 我需要将其通过管道传输到进程(在本例中为 fast-csv)
  3. 完成后,我需要将其发送到下一步(在实际情况下,发送到数据库)
  4. 在真实场景中,我需要等待数据库更新完成
  5. 下一个打开下一个文件流
  6. 处理
  7. 添加
  8. 重复...

所以下面的代码“应该”做到这一点,但承诺不会等待解决。 Await 仅适用于异步函数(并且流似乎会主动忽略任何使用 await 的尝试)

import { parseString } from '@fast-csv/parse';
import * as fs from "fs";

async function IHateStreams (){
    /** Lets read profiles */
    console.log("1: Reading Program " + profileFS);
    let fileContent = fs.readFileSync(profileFS, 'utf8');
    let dataset : Array<any> = []
    return new Promise((resolve, reject) => {
        parseString(fileContent, {headers: true})
            .on('error', error => console.error(error))
            .on('data', row => dataset.push(row))
            .on('end',  () {
                console.log("2: Inside Done")
                resolve
            });
    })

}

IHateStreams().then(console.log("3: stream done!"));
console.log("4: code done, so running next command with the data")

而不是一个很好的输出:

1: Reading Program ./dbinitdata/ProfileIdName.csv
2: Inside Done
3: stream done!
4: code done

我明白了:

1: Reading Program ./dbinitdata/ProfileIdName.csv 
3: stream done! 
4: code done 
2: Inside Done

【问题讨论】:

  • 你似乎没有调用解决,一方面。 3 实际上不在.then回调 中,因此您将日志记录的结​​果传递给.then,而4 根本不是promise 链的一部分。
  • 我可以接受我的错误,但我不知道我错过了什么。我接受您对 4 的评论,但这是我能想到的显示事件流程的最简单方法。但是请在这里帮助我,我如何获得一个简单的承诺来让一些代码等到结束事件工作?
  • TypeScript 将能够为您提供一些帮助 - 当我尝试使用 ts-node 运行您的代码时,我被告知 profileFS 未定义,您的 on("end" 回调是格式错误并且 .then(console.log("3: stream done!")) 没有意义(如上所述)。修复这些问题并 调用 resolve 至少会以正确的顺序获得 1、2 和 3。
  • 非常感谢,一直没看懂。然后,终于等到了promise的工作,所以终于按我想要的方式工作了。非常感谢。

标签: node.js typescript es6-promise


【解决方案1】:

在所有的闲聊之后,我是如此接近。上面的代码由于 3 个原因而失败。 (如果有人在我的旅程中)

承诺包装似乎有效,上述问题是:

  1. 忘记 .then() 特定于流的东西
  2. 错别字不会带你去任何地方,resolve()
  3. 出于我需要它的目的(不是架构师),创建一个 async 控制函数,并让它假装一切都是顺序的,通过在一个 Promise 中一个又一个流踢一个流。

可能有更简单的方法可以做到这一点,但希望这能带来一些启发。

import { parseString } from '@fast-csv/parse';
import * as fs from "fs";

 const profileFS: string = "tsconfig.json"

async function IHateStreams (){
    /** Lets read profiles */
    console.log("1: Reading Program " + profileFS);
    let fileContent = fs.readFileSync(profileFS, 'utf8');
    let dataset : Array<any> = []
    return new Promise((resolve, reject) => {
        parseString(fileContent, {headers: true})
            .on('error', error => console.error(error))
            .on('data', row => dataset.push(row))
            .on('end',  data => {
                console.log("2: Reading Program " + data);
                resolve();
            }
            });
    })

}
async function iWait (){
    const isThisAPromise = await IHateStreams()
    console.log("3: code done, so running next command with the data")
}

iWait();
console.log("1.99: code done, not in chain")

【讨论】:

  • .then 不是特定于流的,它是promise(和其他“thenables”)的一种方法。
  • 下周我会试着绕着车轴转转:)
  • 什么车轴?请至少更正答案中的信息。
猜你喜欢
  • 2018-04-17
  • 1970-01-01
  • 2022-07-20
  • 1970-01-01
  • 1970-01-01
  • 2020-06-23
  • 2019-09-04
  • 2021-08-03
  • 2020-01-15
相关资源
最近更新 更多