比方说我有这个可观察的地方:
const obs = new Observable((observer) => {
observer.next(0.25);
observer.next(0.75);
observer.next(new ArrayBuffer(100));
observer.complete();
});
我该如何等待带有承诺的每个值?
以下代码将仅返回最后一个值(调用complete()之前的值):
const value = await obs.toPromise();
但是我希望能够一路获取每个值。我可以做这样的事情:
const value1 = await obs.pipe(take(1)).toPromise();
const value2 = await obs.pipe(take(2)).toPromise();
但这不是理想的,因为我每次都必须增加数字,并且take(1000)
仍将返回示例中的内容,即使只有3个值。我正在寻找类似的东西:
const value1 = await obs.pipe(next()).toPromise(); // 0.25
const value2 = await obs.pipe(next()).toPromise(); // 0.75
const value3 = await obs.pipe(next()).toPromise(); // ArrayBuffer(100)
const value4 = await obs.pipe(next()).toPromise(); // null
这更类似于发电机。
有没有办法完成这样的事情?
答案 0 :(得分:0)
这可能正好起作用,因为take(1)完成了可观察项,然后被等待消耗,接下来的一行将产生第二个值为value2的发射。
const observer= new Subject()
async function getStream(){
const value1 = await observer.pipe(take(1)).toPromise() // 0.25
const value2 = await observer.pipe(take(1)).toPromise() // 0.75
return [value1,value2]
}
getStream().then(values=>{
console.log(values)
})
//const obs = new Observable((observer) => {
setTimeout(()=>{observer.next(0.25)},1000);
setTimeout(()=>observer.next(0.75),2000);
更新:使用主题发射。
答案 1 :(得分:0)
您似乎想要的是一种将可观察对象转换为异步可迭代对象的方法,以便您可以“手动”或使用新的for-await-of语言功能来异步迭代其值。 / p>
这里有一个执行此操作的示例(我尚未测试此代码,因此可能存在一些错误):
// returns an asyncIterator that will iterate over the observable values
function asyncIterator(observable) {
const queue = []; // holds observed values not yet delivered
let complete = false;
let error = undefined;
const promiseCallbacks = [];
function sendNotification() {
// see if caller is waiting on a result
if (promiseCallbacks.length) {
// send them the next value if it exists
if (queue.length) {
const value = queue.shift();
promiseCallbacks.shift()[0]({ value, done: false });
}
// tell them the iteration is complete
else if (complete) {
while (promiseCallbacks.length) {
promiseCallbacks.shift()[0]({ done: true });
}
}
// send them an error
else if (error) {
while (promiseCallbacks.length) {
promiseCallbacks.shift()[1](error);
}
}
}
}
observable.subscribe(
value => {
queue.push(value);
sendNotification();
},
err => {
error = err;
sendNotification();
},
() => {
complete = true;
sendNotification();
});
// return the iterator
return {
next() {
return new Promise((resolve, reject) => {
promiseCallbacks.push([resolve, reject]);
sendNotification();
});
}
}
}
与“等待语言”功能一起使用:
async someFunction() {
const obs = ...;
const asyncIterable = {
[Symbol.asyncIterator]: () => asyncIterator(obs)
};
for await (const value of asyncIterable) {
console.log(value);
}
}
不使用等待语言功能而使用:
async someFunction() {
const obs = ...;
const it = asyncIterator(obs);
while (true) {
const { value, done } = await it.next();
if (done) {
break;
}
console.log(value);
}
}