2017-10-02 15 views
-3

私はこの問題を理解する方法を探していましたが、私の検索スキルが上手くいかない場合はお詫びします。連鎖してES6の呼び出しを呼び出す

私の問題:私はAPIをフェッチしており、すべてのデータが完全にロードされた時点を知りたいと思います。ドキュメントを読んで、私はフェッチでステートメントをチェーン化できると思われ、それはうまくいくと思っていました。しかし、彼らはすべて、前のことを待つことなく、同時に終了するように見えるように見える。

は、ここに私のコードです:それは非同期である場合

fetch(myUrl, { 
    method: 'post', 
    headers: { 
     'Content-Type': 'application/json; charset=utf-8',    
    }, 
    credentials: 'include',   
    body: data 
    })         
     .then(fetchStatus) 
     .then(json) 
     .then(function(msg){          
      showSearchResults(); 
      setTimeout(function(){ console.log("Next then should fire after this"); }, 4000);         
     }) 
     .then(function(){ 
      return console.log("The 2nd is firing!");         
     }); 

function fetchStatus(response) { 
    if (response.status >= 200 && response.status < 300) { 
     return Promise.resolve(response) 
    } else { 
     return Promise.reject(new Error(response.statusText)) 
    } 
} 

function json(response) { 
    return response.json() 
} 

は、これは素晴らしいですが、これらのイベントは、私が以前で作成されたコンテンツを操作しようとしていますという事実による同期する必要がありますコール、showSearchResults();

ご迷惑をおかけして申し訳ありません。

+0

...:あなたが連鎖setTimeoutのオフ.thenする場合は

同様に、あなたのような何かを書くことができ} '関数表記法。それは多くの冗長を省くことができ、 'var self = this'のダンスを避けることができます。 – tadman

+0

Promise.allの 'showSearchResults'をラップし、解決するまで待ちます – maioman

+0

問題が何であるか不明です。単一の 'fetch'呼び出しがあり、そのチェーンの各ハンドラは前の呼び出しが実行された後にのみ実行されます。何が問題なの? (showSearchResultsに何らかの引数を与えてはいけませんか?) –

答えて

0

.thenの連鎖する前.thenコールから約束を返されていない限り、そのコードが順次実行される保証はありません。あなたの例では、showSearchResultsの後に2番目のconsole.logを実行したい場合はreturn showSearchResults()とし、.thenを連鎖する必要があります(これはshowSearchResultsが約束を返す場合にのみ有効です;そうでない場合は、どのようにfetchStatusのために持っている)。あなたは{ `MSG =>を忘れないでくださいES6を使用している場合

fetch(url, { method: 'post', etc... }) 
    .then(fetchStatus) 
    .then(json) 
    .then(function(msg){ 
     return new Promise(function(resolve, reject){ 
     setTimeout(function() { 
      console.log("Next then fires after promise resolves"); 
      resolve(); 
     }, 4000) 
     }) 
    }) 
    .then(function(){ 
     console.log("Second is firing") 
    }) 
    .catch(err => console.log(error)) // always remember to catch errors! 
+0

これは私がそれが働くことを望んでいたのとまったく同じです。投稿する前にこの方法を試しましたが、私はPromiseに "新しい"キーワードがなく、しばらく苦労しました。ご協力ありがとうございました! – zadees

-1

then関数への連続した呼び出しは、同じ約束事へのコールバックチェーンを表します。これは最初のものです。彼らは他のすべての約束を表すわけではないので、彼らはとても速く実行します。以下に示すように、あなたが代わりに行う必要があるものですコールバック関数内でそれらをチェーン:

fetch(myUrl, { 
    method: 'post', 
    headers: { 
    'Content-Type': 'application/json; charset=utf-8', 
    }, 
    credentials: 'include', 
    body: data 
    } 
).then((response) => { 
    // fetch promise is resolved 
    fetchStatus(response).then((response) => { 
     // fetchStatus promise is resolved 
     json(response).then((msg) => { 
      // json promise is resolved 
      showSearchResults(); 
      setTimeout(function(){ 
       console.log("Next then should fire after this"); 
      }, 4000); 
      // note that this log will execute before the previous one because 
      // `setTimeout` does not return a promise 
      console.log("The 2nd is firing!"); 
     }); 
    }); 
}); 

function fetchStatus(response) { 
    if (response.status >= 200 && response.status < 300) { 
     return Promise.resolve(response) 
    } else { 
     return Promise.reject(new Error(response.statusText)) 
    } 
} 

function json(response) { 
    return response.json() 
} 
関連する問題