использование 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);
});
660   4  

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() способ встроенный.

.then(() => new Promise((resolve) => setTimeout(resolve, 15000)))

Если вы находитесь внутри .тогда() блок, и вы хотите выполнить 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

    Ничего не найдено.