usando setTimeout sulla catena di promesse

Qui sto cercando di avvolgere la mia testa intorno alle promesse. Qui alla prima richiesta ottengo una serie di link. E alla prossima richiesta ottengo il contenuto del primo link. Ma voglio fare un ritardo prima di restituire il prossimo object promesso. Quindi io uso setTimeout su di esso. Ma mi dà il seguente errore JSON ( without setTimeout() it works just fine )

SyntaxError: JSON.parse: carattere imprevisto alla riga 1 colonna 1 dei dati JSON

mi piacerebbe sapere perché fallisce?

 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); }); 

Per mantenere triggers la catena delle promesse, non puoi usare setTimeout() come hai fatto perché non stai restituendo una promise dal gestore .then() – lo stai restituendo dal callback setTimeout() che non hai bene.

Invece, puoi fare una semplice piccola funzione di delay come questa:

 function delay(t, v) { return new Promise(function(resolve) { setTimeout(resolve.bind(null, v), t) }); } 

E quindi usalo in questo modo:

 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"); }); }); 

Qui stai restituendo una promise dal gestore .then() e quindi è opportunamente incatenato.


Puoi anche aggiungere un metodo di delay all’object Promise e quindi utilizzare direttamente un .delay(x) sulle tue promesse in questo modo:

 function delay(t, v) { return new Promise(function(resolve) { setTimeout(resolve.bind(null, v), t) }); } Promise.prototype.delay = function(t) { return this.then(function(v) { return delay(t, v); }); } Promise.resolve("hello").delay(500).then(function(v) { console.log(v); }); 
 .then(() => new Promise((resolve) => setTimeout(resolve, 15000))) 

Se sei all’interno di un blocco .then () e vuoi eseguire un settimeout ()

  .then(() => { console.log('wait for 10 seconds . . . . '); return new Promise(function(resolve, reject) { setTimeout(() => { console.log('10 seconds Timer expired!!!'); resolve(); }, 10000) }); }) .then(() => { console.log('promise resolved!!!'); }) 

l’output sarà come mostrato di seguito

 wait for 10 seconds . . . . 10 seconds Timer expired!!! promise resolved!!! 

Felice codifica!