2017-03-27 3 views
0

数日前、リソースに到達可能かどうかをチェックする機能を実装しようとしました。私はむしろJSに新しいので、非同期関数を実装するために完全なコードを再構成しなければなりませんでした。here on SOを提案しました。fetchを使用して、リソースが到達可能かどうかをチェックするJavaScript(タイムアウト)

ここでは、上記の@adeneoの回答をもとに、意図したとおりに動作するものが得られました。

ただし、リソースに到達できない場合は2分以上かかるので、fetchコマンドのタイムアウトを実装します。

私は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)) 

私は本当にJSに慣れていないんだと少しはここに失われています。

私が実装した関数で上記のようにタイムアウトを実装するにはどうすればいいですか?

編集:

私の場合には、fetch('/resource-that-may-take-a-while')はもう少し広範囲なので、私は私が既に持っている作業コードの周りに提案Promise.raceをラップしようとしました。

結果は、以前のSO質問からの示唆された機能と、タイムアウトのためのGitHubからの提案の両方を実装するアプローチです。

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

これはラインreturn new Promise((res, rej) => {ためUncaught SyntaxError: Unexpected token returnになります。 mdn 1として

+0

を失敗しました。 'return'キーワードを省略するだけです。 – Johannes

+0

私は間違っているかもしれませんが、私はそこに約束を返す必要があると思います。そうしないと、完全な* inner *関数は何も返しません。 – SaAtomic

+0

fetchまたはtimeout約束が解決または拒否された場合、 'Promise.race'が終了します。 'inner'関数(' rec')はあなたのreturn文に関係なく呼び出されます。さらに、Promiseコールバックから何も返すことはできません。これはコールバックの仕組みです。フェッチが処理されたイベントを処理するには 'p.then'を使います。タイムアウトのケースを処理するには、 'p.catch'(すでに行ったように)を使います。 – Johannes

答えて

1

Promise.race(反復可能)メソッドは、値または理由からで、解決又はできるだけ早く反復可能の解決における約束の一つとして拒否または拒絶する約束を返しますその約束。

あなたがする必要があることは、Promise.race関数に渡す配列に約束を渡すことだけです。そこに戻る必要はありませんが、chk関数のPromiseを返すと、以下のように直接使用できます。 pは/どちらかchkまたはタイムアウトが完了した場合、/は拒否解決あなたは配列の宣言文で返すことはできません

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) 
    }) 
} 
関連する問題