Javascript Rx.Observable.prototype.fromEvent()的奇怪行为

Javascript Rx.Observable.prototype.fromEvent()的奇怪行为,javascript,jquery,rxjs,flatmap,concatmap,Javascript,Jquery,Rxjs,Flatmap,Concatmap,今天我在使用RxJS时遇到了一个奇怪的问题。请帮我检查一下 我正在处理的问题是:“给定一个图像URL数组,将所有图像加载并附加到一个div。” 要演示的所有代码片段如下所示: 开始时,我使用了第一个代码片段 但是,Rx.Observable.prototype.flatMap有时会将图像按错误的顺序放置(文档中注意到这种行为)。因此,我改为使用concatMap(secondsnippet) 这一次,仅加载第一个图像。我花了一些时间检查这个问题。我怀疑事件load不是从image触发的。但最令

今天我在使用RxJS时遇到了一个奇怪的问题。请帮我检查一下

我正在处理的问题是:“给定一个图像URL数组,将所有图像加载并附加到一个div。”

要演示的所有代码片段如下所示:

开始时,我使用了
第一个代码片段

但是,
Rx.Observable.prototype.flatMap
有时会将图像按错误的顺序放置(文档中注意到这种行为)。因此,我改为使用
concatMap
secondsnippet

这一次,仅加载第一个图像。我花了一些时间检查这个问题。我怀疑事件
load
不是从
image
触发的。但最令人困惑的情况是,当我添加一些代码来只收听
image
load
事件时,它向我表明事件被正确触发了。。。(
第三个代码段

然后,我决定使用
$编写另一个版本。Deferred
第四个代码片段

它起作用了

你能告诉我有什么问题吗?多谢各位

由于第一个子观察对象上的
fromEvent(图像“加载”)
未完成,其他子观察对象将永远等待。所以你们应该在第一个事件之后完成子可观测

使用
take(1)

从第二个片段中摘录

...
var loadedImageStream = Rx.Observable
                            .fromEvent(image, 'load')
                            .map(function() {                                  
                                return image;
                             })
...
添加take(1)以完成子可观察项

...
var loadedImageStream = Rx.Observable
                            .fromEvent(image, 'load')
                            .map(function() {                                  
                                return image;
                             })
                            .take(1)
...
编辑:

使用
concatMap
可以按顺序加载图像,因此速度较慢

如果您通过了
索引
,则可以使用
替换
而不是
追加
来维持订单。在这种情况下,您可以使用
flatMap
,它支持快速并发加载

$(function () {
    var imageURLList = [
        'https://placehold.it/500x100',
        'https://placehold.it/500x200',
        'https://placehold.it/500x300',
        'https://placehold.it/500x400',
        'https://placehold.it/500x500'
    ];
    var imagesDOM = $('#images');

    Rx.Observable
        .fromArray(imageURLList)
        .do(function (imageURL) {
            imagesDOM.append(new Image()); // placeholder
        })
        .flatMap(function (imageURL, index) {
            var image = new Image();

            var loadedImageStream = Rx.Observable
                .fromEvent(image, 'load')
                .map(function () {
                    return [image, index];
                })
                .take(1)

            image.src = imageURL;

            return loadedImageStream;
        })
        .subscribe(function (image_index) {
            var image = image_index[0];
            var index = image_index[1];

            imagesDOM.children().get(index).replaceWith(image);
        })
})

请直接在问题中添加最小的相关代码,而不是作为外部链接。谢谢@thatseeyou,你真的救了我!