【问题标题】:Inference with Typescript, Observable and bindCallback method使用 Typescript、Observable 和 bindCallback 方法进行推理
【发布时间】:2017-11-21 09:45:26
【问题描述】:

我正在 nodejstypescript 中编写一个函数来搜索文件中的某些模式。 通过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 发射某种“对”变量,即回调的参数,它是 _findSnippets 函数的最后一个参数.相反,我通过智能感知看到的是 _findSnippetsObs 返回一个 Observable&lt;string&gt;,正如您在此快照中看到的那样

在我看来,智能感知功能,特别是在涉及基于 Observable 的异步行为时,是一个非常重要的工具。

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

【问题讨论】:

    标签: typescript types rxjs observable


    【解决方案1】:

    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,这解释了您通过智能感知看到的内容。

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

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

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

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

    【讨论】:

    • 首先感谢您的回答。它完美地工作。为了确定我已经理解了推理的要点,我想再问你一个问题:R 被推断为string,因为_findSnippets 的回调的第一个输入参数是string。另一方面,在第二种情况下,R 是选择器的返回值,因此它获取选择器返回的任何类型。对吗?
    猜你喜欢
    • 1970-01-01
    • 2011-02-22
    • 1970-01-01
    • 2021-06-02
    • 2023-04-07
    • 2020-10-25
    • 2020-09-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多