I am using a library which uses RxJS and I am brand new to RxJS so, although I have googled and tried to do my own research I am still a bit lost.
This library has a function that returns an observable. That observable really only returns a single message when subscribed but I need to wait for the data contained within that message before my code can continue.
I have read about chaining observables and all of that but what I am really after is a very simple async/await pattern. I notice there is a .toPromise() on the observable which you can await on, which is fine, however it appears that promise is resolved before the full execution of my next() function which results in a timing issue with the variables it was setting.
Does that sound correct? How can I simply await an observable AND all its side effects such as calls to next()?
What I have ended up doing, which works reliably but seems overkill is to wrap in a promise as demonstrated below. Is there a more succinct way?
const result = await new Promise((resolve, reject) => {
const s = jupyter.sessions.create(this._serverConfig,
{
kernel: {name: this._kernelName},
name: this._sessionName,
path: '/path',
type: 'notebook'
});
s.pipe(take(1)).subscribe({
next(x) {
resolve({sessionId: x.response.id, kernelId: x.response.kernel.id});
},
error(err) {
reject(err);
},
});
});
this._sessionId = result.sessionId;
this._kernelId = result.kernelId;
For completeness, this is the old code that is NOT working. In this code the await completes in a race condition with the next function. That is, randomly both sessionId and kernelId are undefined as per the log message that follows the await
s.subscribe({
next(x) {
console.log(x);
sessionId = x.response.id;
kernelId = x.response.kernel.id;
},
error(err) {
console.error('Got an error from kernel creation:')
console.error(err);
},
})
.add(() => {
console.log('Connection subscription exiting');
});
await s.toPromise();
console.log(`Found session id ${sessionId} and kernel id ${kernelId}`);