我有一个observable示例代码来打印一些值
sample4Observable() {
var observable = Observable.create(function (observer) {
for (var i = 1; i <= 4; i++) {
if (i <= 3) {
observer.next(i);
}
if (i === 4) {
setTimeout(() => {
observer.next(i);
observer.complete();
}, 5000);
}
}
});
console.log('just before subscribe');
observable.subscribe({
next: x => console.log('got value ' + x),
error: err => console.error('something wrong occurred: ' + err),
complete: () => console.log('done'),
});
console.log('just after subscribe');
}
输出
just before subscribe
got value 1
got value 2
got value 3
just after subscribe
got value 5
done
我的问题是,当值达到4时,我的循环结束。所以下一个值将是4而不是5.为什么RxJS跳过值4?
为了获得4的值,我可以改变我的代码,如下所示。但在上面的场景中,我有点困惑。任何人都可以解释
setTimeout((i) => {
observer.next(i);
observer.complete();
}, 5000,i);
答案 0 :(得分:1)
设置超时时,内部函数将在经过一段时间后执行。当循环达到i === 4
时,它开始超时,内部函数尚未执行。循环再向前递增i
到5,然后循环终止,因为不再满足条件i <= 4
。在经过5秒后(在i
增加到5之后),超时完成并执行该功能。虽然启动超时时i === 4
为真,但现在执行超时功能时,它是i === 5
。
这与RxJS没有直接关联。这个更简单的例子应该说明一下。只需在浏览器控制台中运行它:
let i = 0;
setTimeout(() => console.log(`the value of i is ${i}`), 500);
i++;
答案 1 :(得分:1)
无论如何,它与RxJS没有任何关联,这就是javascript执行的发生。由于您在false
之前循环播放,因此计数达到4,而i<=4
一次i==4
,您将使用setTimeout
启动一个函数。因此,只要setTimeout
注册,它就不会直接进行评估。 setTimeout
是异步事件,浏览器将其置于名为Event Loop
的内容中。等到javascript的所有同步执行都结束。由于for i++
中的i
值变为5
。然后所有同步执行完成。 Javascript访问Event Loop
来评估异步操作(它们也可以是事件)。那个时间setTimeout
进行评估并等到5000
(5秒),然后它会i
值达到预期的5
。
即使您设置超时0
而非5000
,您也会得到相同的结果,即i = 5
。
由于javascript是单线程的,因此它总是评估同步代码,后跟异步代码。
在调用它时,您可以将i
值作为参数传递给setTimeout
函数。如果i
值直接在函数范围内可用,那么就不会检查全局值。在这里查看MSDN Docs
setTimeout((i) => {
observer.next(i);
observer.complete();
}, 5000,i);