AL-zami AL-zami - 2 months ago 11
JSON Question

using setTimeout on promise chain

Here i am trying to wrap my head around promises.Here on first request i fetch a set of links.and on next request i fetch the content of first link.But i want to make a delay before returning next promise object.So i use setTimeout on it.But it gives me the following JSON error (

without setTimeout() it works just fine
)


SyntaxError: JSON.parse: unexpected character at line 1 column 1 of
the JSON data


i would like to know why it fails?

let globalObj={};
function getLinks(url){
return new Promise(function(resolve,reject){

let http = new XMLHttpRequest();
http.onreadystatechange = function(){
if(http.readyState == 4){
if(http.status == 200){
resolve(http.response);
}else{
reject(new Error());
}
}
}
http.open("GET",url,true);
http.send();
});
}

getLinks('links.txt').then(function(links){
let all_links = (JSON.parse(links));
globalObj=all_links;

return getLinks(globalObj["one"]+".txt");

}).then(function(topic){


writeToBody(topic);
setTimeout(function(){
return getLinks(globalObj["two"]+".txt"); // without setTimeout it works fine
},1000);
});

Answer

To keep the promise chain going, you can't use setTimeout() the way you did because you aren't returning a promise from the .then() handler - you're returning it from the setTimeout() callback which does you no good.

Instead, you can make a simple little delay function like this:

function delay(t) {
   return new Promise(function(resolve) { 
       setTimeout(resolve, t)
   });
}

And, then use it like this:

getLinks('links.txt').then(function(links){
    let all_links = (JSON.parse(links));
    globalObj=all_links;

    return getLinks(globalObj["one"]+".txt");

}).then(function(topic){
    writeToBody(topic);
    // return a promise here that will be chained to prior promise
    return delay(1000).then(function() {
        return getLinks(globalObj["two"]+".txt");
    });
});

Here you're returning a promise from the .then() handler and thus it is chained appropriately.