Подтвердить что ты не робот

Использование setTimeout по цепочке обещаний

Здесь я пытаюсь обернуть голову вокруг promises. Здесь, при первом запросе, я получаю набор ссылок. и при следующем запросе я получаю содержимое первой ссылки. Но я хочу сделать задержку, прежде чем возвращать следующее обещание object.So я использую setTimeout на нем. Но это дает мне следующую ошибку JSON (without setTimeout() it works just fine)

SyntaxError: JSON.parse: неожиданный символ в строке 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);
});
4b9b3361

Ответ 1

Чтобы сохранить цепочку обещаний, вы не можете использовать 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) на вашем promises следующим образом:

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

Ответ 2

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