Search code examples
javascriptes6-promise

Javascript: Why doesn't my own promisified sequence work as given in a tutorial?


In the tutorial there is an example building a sequence of loading actions like below:example link

function getJSON(url) {
  let prom = new Promise((resolve, reject) => {
    setTimeout(()=>{resolve(`I'm am ${url}`);}, (Math.random()*3000 + 1000));
  });
  return prom;
}

let story = {};
story.chapterUrls = ['www.fakegoogle.com', 'www.fakeyahoo.cn', 'www.fakeamazon.ca'];

let sequence = Promise.resolve();

function addHtmlToPage(val) {
    console.log(val);
}

// Loop through our chapter urls
story.chapterUrls.forEach(function(chapterUrl) {
  // Add these actions to the end of the sequence
  sequence = sequence.then(function() {
    return getJSON(chapterUrl);
  }).then(function(chapter) {
    addHtmlToPage(chapter);
  });
})

I've done some modification to it, my own version is like below:

function getJSON(url) {
  let prom = new Promise((resolve, reject) => {
    setTimeout(()=>{resolve(`I am ${url}`);}, (Math.random()*3000 + 1000));
  });
  return prom;
}

let story = {};
story.chapterUrls = ['www.fakeweb1.com', 'www.fakeweb2.com', 'www.fakeweb3.com'];
let sequence;

function addHtmlToPage(val) {
    console.log(val);
}

story.chapterUrls.forEach(function(chapterUrl) {
  sequence = sequence || getJSON(chapterUrl);
  sequence.then(function() {
    return getJSON(chapterUrl);
  }).then(function(chapter) {
    addHtmlToPage(chapter);
  });
})

My theory is, since getJSON already returns a Promise, there is no reason to introduce an initial Promisified value as in the tutorial.

However, my version the loading actions are totally random, while in the example given by the tutorial, the three-step loading actions are always in order.

Could someone point out what the key to a chaining like this is? Does it ALWAYS need an initial value? Never redundant? Thanks.


Solution

  • You still have to assign the result of calling .then back to sequence:

    sequence = sequence.then(...)
    

    Otherwise you will be calling sequence.then() only on the original value of sequence.

    Could someone point out what the key to a chaining like this is?

    What I said above.

    Does it ALWAYS need an initial value?

    Well, you have to start somewhere, but how that happens is up to you.