javascript - 在回调之前和之后添加日志记录的 rxjs 运算符

标签 javascript typescript rxjs rxjs-pipeable-operators

我想把这个:

/* ...inside a pipe */
tap(() => logData('my process')),
tap(() => someCallback()),
tap(() => logDataEnd('my process'),
/* pipe continues */

进入一个接受回调 () => someCallback() 并在其前后添加日志记录副作用的新运算符。我的日志记录函数使用 performance.now(),当我只使用显式 tap 版本时,它们按预期工作*,但我的运算符(operator)都没有做同样的事情。

预期结果

使用我的运算符的管道:

of(null).pipe(
  withLogging(() => callbackA()),
  withLogging(() => callbackB()),
  /* etc. */
)

应该生成如下所示的日志:

Action A start
Action A end
Action B start
Action B end
...

但是我得到这个:

Action A start
Action B start
/* ... rest of the pipe */
Action A end
Action B end

通过查看时间戳,我可以看到 end 日志的时间戳是正确的,但 begin 的时间戳太早了。

我尝试以不同的方式使用 defer 但结果没有改变。

我尝试过的

withLogging<T, R>(project: (value :T) => R): OperatorFunction<T, R> {
  return (source: Observable<T>) =>
  defer(() => of(startLogging())).pipe(
    flatMap(() => source),
    tap(() => stopLogging())
  );
}

我试过用 defer 包裹整个管道,或者只是记录过程的开始,或者做 of(null).pipe 然后把所有的效果在一起。我什至尝试过完全不使用 defer,只是返回一个以 null 开头的管道。什么都没有产生所需的行为。

最佳答案

除非您的 someCallback() 本身是异步的和/或您希望将来对其进行平面映射,否则我不会在这里实现新的运算符。一个简单的 Vanilla 高阶函数将很好地满足您的需求。

function withLogging<A extends unknown[], C>(
  cb: (this: C, ...args: A) => void
) {
  return function(this: C, ...args: A) {
    console.log("before");
    cb.call(this, ...args);
    console.log("after");
  };
}

// snip

function someCallback() {
    console.log('Hello!');
}

someObs$.tap(withLogging(someCallback)); // before, Hello!, after for each pushed element

关于javascript - 在回调之前和之后添加日志记录的 rxjs 运算符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57461030/

相关文章:

javascript - 使用基于 Div 的 JSON 值之一的 JS 选择框隐藏 div

javascript - 使用 addEventListener 添加子元素,但事情出了问题

javascript - Material-ui:如何停止在嵌套组件中传播点击事件

node.js - 无法通过Kubernetes上的Node.Js连接到Elasticsearch(证书链中的自签名证书)

javascript - Angular 绑定(bind)@input 行为无法正常工作

angular - 哪个运营商有条件地链接 Observables?

javascript - 如何检查 FOSJSRoutingBundle 中是否存在路由

c# - 从国家/地区下拉列表中自动选择国家/地区电话代码

dictionary - 角度 6 : No 'Access-Control-Allow-Origin' header is present on the requested resource

rxjs:合并两个流,但在第二个发送事件后取消第一个