использование setTimeout в цепочке обещаний
здесь я пытаюсь обернуть голову вокруг обещаний.Здесь по первому запросу я получаю набор ссылок.и по следующему запросу я получаю содержимое первой ссылки.Но я хочу сделать задержку перед возвращением следующего обещания object.So я использую setTimeout на нем.Но это дает мне следующую ошибку JSON (without setTimeout() it works just fine)
SyntaxError: JSON.разбор: неожиданный символ в строке 1 столбец 1
данные JSON
я хотел бы знать, почему это не удается?
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);
});
4 ответов:
чтобы сохранить цепочку обещаний, вы не можете использовать
setTimeout()так, как вы сделали, потому что вы не возвращаете обещание от.then()обработчик-вы возвращаете его изsetTimeout()обратный вызов, который вам не подходит.вместо этого вы можете сделать простую функцию небольшой задержки, как это:
function delay(t, v) { return new Promise(function(resolve) { setTimeout(resolve.bind(null, v), t) }); }и затем использовать его в таком виде:
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"); }); });вот вы возвращаете обещание от
.then()обработчик и таким образом он прикован соответственно.
вы также можете добавить метод задержки в объект Promise, а затем напрямую использовать
.delay(x)метод на ваши обещания, как это: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); });или библиотека обещаний Bluebird который уже имеет
.delay()способ встроенный.
Если вы находитесь внутри .тогда() блок, и вы хотите выполнить 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!!!'); })выход, как показано ниже
wait for 10 seconds . . . . 10 seconds Timer expired!!! promise resolved!!!Удачи В Кодировании!
более короткая версия ES6 ответа:
const delay = t => new Promise(resolve => setTimeout(resolve, t));и тогда вы можете сделать:
delay(3000).then(() => console.log('Hello'));
Comments