2016-09-16 3 views
35

Hier versuche ich meinen Kopf um Versprechen zu wickeln.Hier auf erste Anfrage hole ich eine Reihe von Links.und bei der nächsten Anfrage hole ich den Inhalt der ersten Link.Aber ich möchte eine Verzögerung vor nächste Versprechen der Rückkehr object.So i setTimeout verwenden auf it.But es gibt mir die folgende JSON Fehler (without setTimeout() it works just fine)mit setTimeout auf Versprechen Kette

SyntaxError: JSON.parse: unexpected character at line 1 column 1 of the JSON data

ich möchte wissen, warum es nicht funktioniert?

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

Beachten Sie, dass 'return' funktionsspezifisch ist und nur zu der übergeordneten Funktion zurückkehrt und dass Sie nicht von einer asynchronen Methode zurückkehren können. – adeneo

+1

Beachten Sie, dass es [viel bessere Möglichkeiten] (http://stackoverflow.com/q/28250680/1048572) gibt, diesen Code zu strukturieren, als ein 'globalObj' zu verwenden. – Bergi

+0

Wohin wirft 'JSON.parse'? Ich finde es schwer zu glauben, dass, ob es ein "setTimeout" in einem "then" Callback gibt, den Anruf im vorherigen 'then' Callback beeinflusst. – Bergi

Antwort

68

Um das Versprechen Kette gehen, halten Sie nicht setTimeout() so, wie Sie taten verwenden können, weil Sie nicht ein Versprechen aus dem .then() Handler zurückkehrt - Sie sind es aus dem setTimeout() Rückruf Rückkehr, die tut du nicht gut.

Stattdessen können Sie eine einfache kleine Verzögerung Funktion wie folgt machen:

function delay(t, v) { 
    return new Promise(function(resolve) { 
     setTimeout(resolve.bind(null, v), t) 
    }); 
} 

Und es dann wie folgt verwenden:

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

Hier bist du ein Versprechen aus dem .then() Handler Rückkehr und somit ist es in geeigneter Weise verkettet.


Sie können auch eine Verzögerung Methode zum Versprechen Objekt hinzufügen und dann eine .delay(x) Methode auf Ihre Versprechen wie diese direkt verwenden:

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

Oder die Bluebird promise library verwenden, die hat bereits die .delay() Methode eingebaut.

+0

Auflösungsfunktion ist die Funktion innerhalb dann() .. so setTimeout (auflösen, t) bedeutet die setTimeout (Funktion() {return ....}, t) ist es nicht ... also warum es funktioniert? –

+0

@ AL-zami - 'delay()' gibt eine Zusage zurück, die nach dem 'setTimeout()' aufgelöst wird. – jfriend00

+0

Ich habe einen Versprechen Wrapper für setTimeout erstellt, um eine Zusage leicht zu verzögern. https://github.com/zengfenfei/delay – Kevin

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

Bitte erläutern Sie, warum dies besser ist als die bereits angenommene Antwort. Antworte nicht, wenn du nichts hinzufügst. – klutt

+3

Liebe es! Schön und kurz! –

Verwandte Themen