usando setTimeout na cadeia de promises

Aqui eu estou tentando envolver minha cabeça em torno promises.Aqui na primeira solicitação eu buscar um conjunto de links.and na próxima solicitação eu busco o conteúdo do primeiro link.Mas eu quero fazer um atraso antes de retornar o próximo object promise.Então eu uso setTimeout nele.Mas dá-me o seguinte erro JSON ( without setTimeout() it works just fine )

SyntaxError: JSON.parse: caractere inesperado na linha 1, coluna 1 dos dados JSON

Eu gostaria de saber por que isso falha?

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

Para manter a cadeia de promises, você não pode usar setTimeout() da maneira que você fez porque você não está retornando uma promise do manipulador .then() – você está retornando a partir do callback setTimeout() que você não Boa.

Em vez disso, você pode fazer uma function simples de atraso como esta:

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

E, em seguida, use-o assim:

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

Aqui você está retornando uma promise do manipulador .then() e, portanto, é encadeado apropriadamente.


Você também pode adicionar um método de atraso ao object Promise e usar diretamente um .delay(x) em suas promises como esta:

 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 você estiver dentro de um bloco .then () e quiser executar um 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!!!'); }) 

saída será como mostrado abaixo

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

Codificação Feliz!