使用Typescript,Observable和bindCallback方法进行推理

时间:2017-11-20 22:19:37

标签: typescript types rxjs observable

我正在 nodejs typescript 中编写一个函数来搜索文件中的某些模式。 通过readline节点包提供的函数逐行读取文件。

代码看起来或多或少像这样

import * as readline from 'readline';
....
....
function _findSnippets(
    filePath: string,
    startSnippetToken: string,
    endSnippetToken: string,
    callback: (filePath: string, snippets: Array<Array<string>>) => void
) {
          // do some prep stuff
    const snippet = new Array<string>();
    const rl = readline.createInterface({
        input: fs.createReadStream(filePath),
        crlfDelay: Infinity
    });
    rl.on('line', (line: string)  => {
        let isLineToBeAddedToSnippet: boolean;
               // do the core of the logic to set the correct value for
               // the variable isLineToBeAddedToSnippet
        if (isLineToBeAddedToSnippet) {
             snippet.push(line);
        }
    })
    rl.on('close', ()  => {
        callback(filePath, snippet);
    })
}

我想通过Observable模式使用上面定义的函数,所以我使用Observable的bindCallback函数来创建一个在执行回调时发出的Observable。

执行绑定的代码如下

const _findSnippetsObs = Observable.bindCallback(_findSnippets);

现在我想通过推理看到Typescript显示_findSnippetsObs函数返回一个Observable,它发出某种“变量对”,即回调的参数,它是{{的最后一个参数。 1}}功能。相反,我通过intellisense看到的是_findSnippets返回_findSnippetsObs,你可以在这个快照中看到 enter image description here

在我看来,intellisense功能,特别是基于异步Observable的行为,是一个非常重要的工具。

因此,如果有人能帮助我纠正这个问题,我将不胜感激。

1 个答案:

答案 0 :(得分:2)

bindCallback方法解析为对BoundCallbackObservable.create的调用,其numerous overloads

你的_findSnippets函数需要三个字符串参数和一个回调参数,所以相关的重载是这两个:

static create<T, T2, T3, R>(
  callbackFunc: (v1: T, v2: T2, v3: T3, callback: (result: R) => any) => any,
  selector?: void,
  scheduler?: IScheduler
): (v1: T, v2: T2, v3: T3) => Observable<R>;

static create<T, T2, T3, R>(
  callbackFunc: (v1: T, v2: T2, v3: T3, callback: (...args: any[]) => any) => any,
  selector: (...args: any[]) => R,
  scheduler?: IScheduler
): (v1: T, v2: T2, v3: T3) => Observable<R>;

您尚未指定选择器,因此匹配第一个重载 - 因为忽略了回调的多余参数。该重载的匹配将R推断为string,这解释了您通过intellisense看到的内容。

对于接收多个参数的回调,需要有一些机制将接收到的参数打包成可以从observable发出的东西 - 某些东西可以是数组或对象。为此,您需要指定一个选择器。例如:

const _findSnippetsObs = Observable.bindCallback(
  _findSnippets,
  (filePath: string, snippets: Array<Array<string>>) => ({ filePath, snippets })
);

在这里,指定选择器将看到调用匹配上述第二个重载,observable将发出具有filePathsnippets属性的对象。

此外,您可能希望查看bindNodeCallback并考虑为error事件添加一个侦听器 - 如果它们有可能由readline发出。这样做将允许使用可观察流来报告和处理错误。