我想把这个:
/* ...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/