2017-03-27 1 views
0

Vor ein paar Tagen habe ich versucht, eine Funktion zu implementieren, um zu überprüfen, ob eine Ressource erreichbar ist oder nicht. Ich bin ziemlich neu in JS und musste meinen kompletten Code restrukturieren, um die Async-Funktion zu implementieren, die here on SO vorgeschlagen wurde.JavaScript mit Abruf, um zu prüfen, ob eine Ressource erreichbar ist, mit einer Zeitüberschreitung

Jetzt habe ich die Dinge wie geplant funktioniert, mit der oben genannten Antwort von @adeneo.

Allerdings dauert der Vorgang 2 Minuten +, wenn die Ressource nicht erreichbar ist, also möchte ich ein Timeout für den fetch Befehl implementieren.

Ich kam in this answer on a GitHub issue:

var p = Promise.race([ 
    fetch('/resource-that-may-take-a-while'), 
    new Promise(function (resolve, reject) { 
    setTimeout(() => reject(new Error('request timeout')), 5000) 
    }) 
]) 
p.then(response => console.log(response)) 
p.catch(error => console.log(error)) 

Ich bin wirklich nicht vertraut mit JS und bin ein bisschen hier verloren.

Wie kann ich das Timeout implementieren, wie oben in der von mir implementierten Funktion vorgeschlagen, die auf der SO-Frage steht, die ich erwähnt habe?

edit:

Da in meinem Fall die fetch('/resource-that-may-take-a-while') etwas umfangreicher ist, ich habe versucht, die vorgeschlagen Promise.race um den Arbeitscode zu wickeln habe ich bereits.

Das Ergebnis ist ein Ansatz, um sowohl die vorgeschlagene Funktion aus der vorherigen SO-Frage als auch den Vorschlag von GitHub für eine Zeitüberschreitung zu implementieren.

function chk(target, times, delay) { 
    var p = Promise.race([ 
    return new Promise((res, rej) => { 

     (function rec(i) { 
      fetch(target, {mode: 'no-cors'}).then((r) => { 
       res(r); 
      }).catch(err => { 
       if (times === 0) 
        return rej(err); 

       setTimeout(() => rec(--times), delay) 
      }); 
     })(times); 

    }), 
    new Promise(function (resolve, reject) { 
    setTimeout(() => reject(new Error('request timeout')), 5000) 
    }) 
]) 
p.catch(error => console.log("timeout")); 
} 

Dies führt zu Uncaught SyntaxError: Unexpected token return für die Linie return new Promise((res, rej) => {.

+0

Sie nicht in einer Array-Deklaration Anweisung zurückgeben kann. Schließen Sie einfach das Schlüsselwort return aus. – Johannes

+0

Ich könnte mich irren, aber ich denke, ich muss das Versprechen dort zurückgeben, sonst gibt die komplette * innere * Funktion nie etwas zurück. – SaAtomic

+0

'Promise.race' wird beendet, wenn entweder das Fetch- oder Timeout-Versprechen aufgelöst oder abgelehnt wird. Die 'innere' Funktion (' rec') wird unabhängig von Ihrer Rückgabeanweisung aufgerufen. Außerdem können Sie nichts vom Promise-Rückruf zurückgeben - so funktionieren Rückrufe. Verwenden Sie 'p.then ', um das Ereignis zu behandeln, für das der Abruf ausgeführt wurde. Verwenden Sie 'p.catch' (wie Sie es bereits getan haben), um den Timeout-Fall zu behandeln. – Johannes

Antwort

1

Gemäß der mdn:

Die Promise.race (abzählbaren) Methode gibt ein Versprechen, dass, sobald eine der Versprechungen in den iterable Entschlüssen oder ablehnt, mit dem Wert oder Grund löst oder lehnt ab dieses Versprechen.

Alles, was Sie tun müssen, ist, die Versprechen in das Array zu übergeben, das Sie an die Promise.race-Funktion übergeben. Sie müssen nicht dorthin zurückkehren - aber Sie können das Versprechen der chk Funktion zurückgeben, um es direkt zu benutzen, wie unten gezeigt. p löst/verwirft, wenn entweder chk oder das Timeout abgeschlossen/nicht

var p = Promise.race([ 
    chk(t, 3, 1000), 
    new Promise(function (resolve, reject) { 
    setTimeout(() => reject(new Error('request timeout')), 5000) 
    }) 
]) 

p.catch(error => console.log('timeout')) 

function chk (target, times, delay) { 
    return new Promise((res, rej) => { 
    (function rec (i) { 
     fetch(target, { mode: 'no-cors' }).then((r) => { 
     res(r) 
     }).catch(err => { 
     if (times === 0) { 
      return rej(err) 
     } 

     setTimeout(() => rec(--times), delay) 
     }) 
    })(times) 
    }) 
} 
Verwandte Themen