使用回调对方法进行主观化
subjectify methods with callbacks
我经常使用 promisify
method,它将带有回调签名的方法(例如 fucntion fn(cb) { ... }
)转换为 return 为 Promise
的方法。它可以使源代码更干净、更紧凑。到目前为止一切顺利。
略有不同的是,方法具有回调方法,但回调会被多次调用。在那种情况下,Promise
无法解决问题,因为 promise 只能执行一次。
理论上,这些方法可以 return 和 Subject
。 (例如 BehaviorSubject
)然后会被触发多次。
这让我想知道:
有什么subjectify
方法可以帮我做这个吗?
例如:当有一个解析大文档的方法时,它可能很有用。要报告其进度,它可以使用回调方法。但是将其包装在 Subject
中可能更方便。
有一些运算符可以帮助您将回调转换为可观察的
https://rxjs-dev.firebaseapp.com/api/index/function/fromEventPattern
但您可以像下面这样轻松地将主题集成到回调
const progress=new Subject()
myEvent.on('progress', (p)=>{
progress.next(p)
})
如果你的回调被重复调用并且你想通知事件流作为调用回调的结果,你可能需要考虑创建一个 Observable。
让我们以节点 readline
函数为例,它接受一个回调,该回调在读取每一行时被触发,第二个回调在到达文件末尾时调用。
在这种情况下,我们可以创建一个 Observable,它为读取的每一行发出信号并在到达末尾时完成,如下例所示
function readLineObs(filePath: string) => {
return new Observable(
(observer: Observer<string>): TeardownLogic => {
const rl = readline.createInterface({
input: fs.createReadStream(filePath),
crlfDelay: Infinity,
});
rl.on('line', (line: string) => {
observer.next(line);
});
rl.on('close', () => {
observer.complete();
});
},
);
};
我经常使用 promisify
method,它将带有回调签名的方法(例如 fucntion fn(cb) { ... }
)转换为 return 为 Promise
的方法。它可以使源代码更干净、更紧凑。到目前为止一切顺利。
略有不同的是,方法具有回调方法,但回调会被多次调用。在那种情况下,Promise
无法解决问题,因为 promise 只能执行一次。
理论上,这些方法可以 return 和 Subject
。 (例如 BehaviorSubject
)然后会被触发多次。
这让我想知道:
有什么subjectify
方法可以帮我做这个吗?
例如:当有一个解析大文档的方法时,它可能很有用。要报告其进度,它可以使用回调方法。但是将其包装在 Subject
中可能更方便。
有一些运算符可以帮助您将回调转换为可观察的 https://rxjs-dev.firebaseapp.com/api/index/function/fromEventPattern
但您可以像下面这样轻松地将主题集成到回调
const progress=new Subject()
myEvent.on('progress', (p)=>{
progress.next(p)
})
如果你的回调被重复调用并且你想通知事件流作为调用回调的结果,你可能需要考虑创建一个 Observable。
让我们以节点 readline
函数为例,它接受一个回调,该回调在读取每一行时被触发,第二个回调在到达文件末尾时调用。
在这种情况下,我们可以创建一个 Observable,它为读取的每一行发出信号并在到达末尾时完成,如下例所示
function readLineObs(filePath: string) => {
return new Observable(
(observer: Observer<string>): TeardownLogic => {
const rl = readline.createInterface({
input: fs.createReadStream(filePath),
crlfDelay: Infinity,
});
rl.on('line', (line: string) => {
observer.next(line);
});
rl.on('close', () => {
observer.complete();
});
},
);
};