node.js - 保持对管道操作员之间变量的访问
问题描述
我一直在尝试在节点应用程序中使用 Rxjs。fileList$
是fs.readdirsync
(字符串数组)的返回值。
第一个map()
有一个名为文件名的参数。
flatMap() readFileAsObservable()
用于bindNodeCallback(fs.readFile)
读取文件。
我的课Testian
需要 2 个参数;yaml-js
通过读取文件和filename
从第一个映射创建的对象。如何filename
在我指示的管道中访问?
fileList$
.pipe(
map((filename: string) => `${resolvedDirPath}/${filename}`),
flatMap(
(filePath: string) => readFileAsObservable(filePath, 'utf8') as Observable<string>
),
map((fileData: string) => yaml.safeLoad(fileData) as ITestYaml),
map((testYaml: ITestYaml) => new Testian(testYaml, [I want to use filename here])),
flatMap((testYaml: Testian) => {
const prom: Promise<{}> = activeTests.set(testYaml);
outgoing.sendTest(testYaml);
return from(prom);
})
)
解决方案
这在任何涉及链式函数的 API 中都被类似地处理,例如 Promise。
临时变量
临时变量可用于存储超出应访问它的函数范围的值。这是一个简单但非惯用的解决方法:
let filename;
fileList$.pipe(
map((_filename) => {
filename = _filename;
return `${resolvedDirPath}/${filename}`;
}),
flatMap((filePath) => readFileAsObservable(filePath, 'utf8')),
map((fileData) => yaml.safeLoad(fileData)),
map((testYaml) => new Testian(testYaml, filename)),
flatMap((testYaml) => {
const prom = activeTests.set(testYaml);
outgoing.sendTest(testYaml);
return from(prom);
})
)
竞争条件可能存在问题,具体取决于特定的 observable。
嵌套函数
filename
可以嵌套使用的函数以从父范围访问变量:
fileList$.pipe(
flatMap((filename) => of(`${resolvedDirPath}/${filename}`).pipe(
flatMap((filePath) => readFileAsObservable(filePath, 'utf8')),
map((fileData) => yaml.safeLoad(fileData)),
map((testYaml) => new Testian(testYaml, filename)
),
flatMap((testYaml) => {
const prom = activeTests.set(testYaml);
outgoing.sendTest(testYaml);
return from(prom);
})
)
传递价值
在可能的情况下,该变量可以与其他其他结果一起传递:
fileList$.pipe(
map((filename) => [filename, `${resolvedDirPath}/${filename}`]),
flatMap(
([filename, filePath]) => forkJoin(filename, readFileAsObservable(filePath, 'utf8')),
),
map(([filename, fileData]) => [filename, yaml.safeLoad(fileData) as ITestYaml)],
map(([filename, testYaml]) => new Testian(testYaml, filename)),
flatMap((testYaml) => {
const prom = activeTests.set(testYaml);
outgoing.sendTest(testYaml);
return from(prom);
})
)
异步..等待
如果流允许切换到 promise 和async..await
,则可以这样做,因为函数作用域的问题在函数中不存在async
。
fileList$.pipe(
flatMap(async (filename) => {
const filePath = `${resolvedDirPath}/${filename}`;
const fileData = await readFileAsObservable(filePath, 'utf8').toPromise();
let testYaml = yaml.safeLoad(fileData);
testYaml = new Testian(testYaml, filename);
const prom = activeTests.set(testYaml);
outgoing.sendTest(testYaml);
return prom;
})
)
由于这个 observable 已经使用flatMap
和承诺,它可以单独使用承诺安全地编写。RxJS observables 有一些不适合 promise 的用例,但这不是其中之一。
推荐阅读
- javascript - 将两个数组中的元素分组到另一个数组的一个元素
- javascript - 从概率中获得正确结果时遇到问题(javascript初学者)
- python-3.x - 网页抓取搜索参数混淆
- ruby-on-rails - Rspec 使用 Request 和 rswag 测试 sign_in (Devise) 的问题
- python - 如何添加 Uniqueconstraint 而不会导致旧表 velues 出现问题
- authentication - 使用 aws amplify 将身份验证添加到现有的 javascript 项目
- laravel - 在范围搜索中以一对多关系获取最后注册的项目
- nssecurecoding - 具有原始类型的 NSSecureCoding
- javascript - 我无法通过此错误:无法读取未定义的属性“地图”
- kubernetes - 为 kubernetes operator 提供 kubectl 的自定义命令行选项