Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between do and subscribe in rxjs

In this JS Bin I have some observables that load a mocked paginated data source. getPageFromServer loads a page of data from the server starting at the given index:

function getPageFromServer( index ) {

  index = index || 0;

  var values = [];
  var nextIndex;

  for(var i = 0; i< 3; i++) {
    var newValue = index + i;
    if(newValue < 10){
      values.push( newValue );
      nextIndex = newValue + 1;
    }
    else {
      nextIndex = undefined;
    }
  }

  data = { values: values, nextIndex: nextIndex };

  return Rx.Observable.return(data).delay(500);
}

getPagedItems then loads the pages and concats the multiple observables into one so that we just get an observable of all the values from all the pages:

function getPagedItems(index) {
  return getPageFromServer(index)
    .flatMap(function (response) {
      var result = Rx.Observable.from(response.values);

      if(response.nextIndex !== undefined){
        return result.concat( getPagedItems(response.nextIndex) );
      } else {
        return result;
      }

  });
}

This gives me my expected result:

"page received: 1"
"page received: 2"
"page received: 3"
"page received: 4"
"page received: 5"
"page received: 6"
"page received: 7"
"page received: 8"
"page received: 9"
"complete"

However if I add a do to the end of getPagedItems:

function getPagedItems(index) {
  return getPageFromServer(index)
    .flatMap(function (response) {
      var result = Rx.Observable.from(response.values);

      if(response.nextIndex !== undefined){
        return result.concat( getPagedItems(response.nextIndex) );
      } else {
        return result;
      }
  })
  .do( function ( result) { console.log( "do: " + result); } );
}

I get each value the number of times equal to the number of observables we have created in the flatmap:

"starting..."
"do: 0"
"page received: 0"
"do: 1"
"page received: 1"
"do: 2"
"page received: 2"
"do: 3"
"do: 3"
"page received: 3"
"do: 4"
"do: 4"
"page received: 4"
"do: 5"
"do: 5"
"page received: 5"
"do: 6"
"do: 6"
"do: 6"
"page received: 6"
"do: 7"
"do: 7"
"do: 7"
"page received: 7"
"do: 8"
"do: 8"
"do: 8"
"page received: 8"
"do: 9"
"do: 9"
"do: 9"
"do: 9"
"page received: 9"
"complete"

Please explain to me why "do" is firing multiple times but "onNext" in the subscription is only firing once.

Many Thanks

like image 585
Roaders Avatar asked Apr 28 '26 01:04

Roaders


1 Answers

I figured out this answer about 5 minutes after I posted the question!

The reason that the do fires multiple times is because I am calling the loadCommentThreads recursively so each nested call to loadComment threads has a do in the pipeline before the message returns to the parent calling function instance.

like image 167
Roaders Avatar answered Apr 30 '26 14:04

Roaders