1

我试图把这个:

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

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

预期成绩

使用我的运营商的管道:

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。没有任何东西产生期望的行为。

4

1 回答 1

1

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

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
于 2019-08-12T12:31:54.003 回答