2017-05-25 22 views
0

今日、私はRxJSを使用するときに奇妙な問題を見ました。それを調べるのを手伝ってください。Rx.Observable.prototype.fromEvent()の奇妙な動作

私が取り組んでいる問題は次のとおりです。「画像URLの配列を指定すると、すべての画像をロードしてdivに追加する」

すべてのコードスニペットを実証するためには、ここにある:初め

https://pastebin.com/F3ZkH3F8

、私はthe first snippetを使用。

ただし、Rx.Observable.prototype.flatMapは画像を間違った順序で表示することがあります(この動作はドキュメントに記載されています)。そこで、concatMapsecond snippet)を使用するように変更しました。

今回は、最初の画像のみが読み込まれます。私はしばらく時間をかけて問題を点検した。私はイベントloadimageからトリガーされていないことを疑う。しかし、最も紛らわしい状況は、imageloadイベントだけを聞くコードを追加すると、イベントが正しくトリビュートされていることがわかりました。(third snippet

次に、$.Deferredfourth snippet)を使用して別のバージョンを作成することにしました。

正常に機能しました...

問題点は教えてください。どうもありがとうございました!

+1

最小限の関連コードを質問に直接入力してください。外部リンクではありません。 – KevinO

答えて

1

最初の部分観測可能な部分のfromEvent(image, 'load')は完了していないため、他の部分観測部分は永遠に待機しています。ですから、最初のイベントの後では、サブ観測可能にする必要があります。

take(1)を使用してください。 2番目のスニペットから

抜粋

... 
var loadedImageStream = Rx.Observable 
          .fromEvent(image, 'load') 
          .map(function() {         
           return image; 
          }) 
... 

(1)サブ観測可能

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

EDIT完了するために、テイクを追加:concatMapを使用して

は、画像を読み込むますがシーケンシャルなので遅いです。

indexを渡す場合は、appendの代わりにreplaceを使用して注文を維持できます。この場合、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); 
     }) 
}) 
+0

ありがとうございました@ thatseeyou、あなたは本当に私を救った! –