Aqui estou eu tentando envolver minha cabeça em torno de promessas. Aqui, na primeira solicitação, eu busco um conjunto de links. E na próxima solicitação, busco o conteúdo do primeiro link. Mas eu quero atrasar antes de retornar o próximo objeto de promessa. setTimeout nele. Mas me dá o seguinte erro JSON ( without setTimeout() it works just fine
)
SyntaxError: JSON.parse: caractere inesperado na linha 1 coluna 1 dos dados JSON
gostaria de saber por que 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);
});
javascript
json
promise
AL-zami
fonte
fonte
return
é específico da função e retorna apenas para a função pai, e que você não pode retornar de um método assíncrono.globalObj
.JSON.parse
joga? Acho difícil acreditar que a existência desetTimeout
umthen
retorno de chamada afeta a chamada dothen
retorno de chamada anterior .Respostas:
Para manter a cadeia de promessas em andamento, você não pode usar
setTimeout()
a maneira como fez porque não está retornando uma promessa do.then()
manipulador - você a está retornando dosetTimeout()
retorno de chamada, o que não adianta nada.Em vez disso, você pode fazer um pequeno atraso simples funcionar como este:
E, em seguida, use-o assim:
Aqui, você está devolvendo uma promessa do
.then()
manipulador e, portanto, ela é devidamente encadeada.Você também pode adicionar um método de atraso ao objeto Promise e usar diretamente um
.delay(x)
método em suas promessas como este:Ou use a biblioteca de promessa Bluebird, que já possui o
.delay()
método integrado.fonte
delay()
retorna uma promessa que será resolvida após osetTimeout()
.v
é um valor opcional com o qual você deseja que a promessa de atraso resolva e, assim, transmita a cadeia de promessa.resolve.bind(null, v)
está no lugar defunction() {resolve(v);}
Qualquer funcionará.ATUALIZAR:
quando eu preciso dormir na função assíncrona eu coloco
fonte
A versão ES6 mais curta da resposta:
E então você pode fazer:
fonte
reject
opção, por exemplo, para validação eslint, entãoconst delay = ms => new Promise((resolve, reject) => setTimeout(resolve, ms))
Se você estiver dentro de um .then () bloco e você quer executar um setTimeout ()
a saída será como mostrado abaixo
Happy Coding!
fonte
Em node.js, você também pode fazer o seguinte:
fonte
util
está sendo polyfilled incorretamente. Você está usando um bundler ou algo assim?