Ici, je suis en train d'essayer de comprendre les promesses.Voici à la première demande, je vais chercher un ensemble de liens. Et à la prochaine demande, je vais chercher le contenu du premier lien. setTimeout sur it.Mais cela me donne l'erreur JSON suivante (without setTimeout() it works just fine
)
SyntaxError: JSON.parse: caractère inattendu à la ligne 1 colonne 1 des données JSON
je voudrais savoir pourquoi il échoue?
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);
});
Pour maintenir la chaîne de promesses, vous ne pouvez pas utiliser setTimeout()
comme vous le faites parce que vous ne renvoyez pas de promesse du gestionnaire .then()
, vous la renvoyez à partir de setTimeout()
rappel qui ne vous sert à rien.
Au lieu de cela, vous pouvez créer une simple fonction de délai comme celle-ci:
function delay(t, v) {
return new Promise(function(resolve) {
setTimeout(resolve.bind(null, v), t)
});
}
Et puis utilisez-le comme ceci:
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");
});
});
Ici, vous retournez une promesse du gestionnaire .then()
et elle est donc chaînée correctement.
Vous pouvez également ajouter une méthode de délai à l'objet Promise, puis utiliser directement une méthode .delay(x)
sur vos promesses, comme suit:
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);
});
Ou bien, utilisez le bibliothèque de promesses Bluebird qui contient déjà la méthode .delay()
.
.then(() => new Promise((resolve) => setTimeout(resolve, 15000)))
La version ES6 plus courte de la réponse:
const delay = t => new Promise(resolve => setTimeout(resolve, t));
Et alors tu peux faire:
delay(3000).then(() => console.log('Hello'));
Si vous êtes dans un bloc . Then () et que vous voulez exécuter 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!!!');
})
comme indiqué ci-dessous
wait for 10 seconds . . . .
10 seconds Timer expired!!!
promise resolved!!!
Bon codage!