Angular 6プロジェクトでいくつかの提案と、ベストプラクティスのヒントが必要です。
以下にいくつかの擬似コードを示します(タイプミスは無視してください)が、基本的にはそれが起こっていることです。プロジェクトは、ユーザーに表示する前に、新しい新しいデータを取得して処理するために、いくつかの手順を実行します。私がやりたいのは、それが完了するまですべてのステップ1を実行し、次にステップ2に進み、完了するとステップ3に進むということです。これは、一部のステップでは、要求を行う前に前のステップからの応答が必要なためです。つまり、各ステップが終了するのを待ってから、次のステップに進む必要があります。しかし、非同期関数には少し問題があります。
var token;
mainFunction(){
step1();
console.log("Done with step 1");
step2();
console.log("Done with step 2");
step3();
console.log("Done with step 3");
}
step1(){
console.log("Step 1...");
var data1 = getData();
// Does things with data1
}
step2(){
console.log("Step 2...");
var data2 = getData();
// Does things with data2
}
step3() {
console.log("Step 3...");
var data3 = getData();
// Does things with data3
}
async getData(){
await getAccessToken();
var result;
console.log("Getting data...");
// Makes a request to an API.
this.http.post("URL", token)
.map(response => response.json())
.toPromise()
.then((response: any) => {
console.log("Got the data!");
// Processing the response
result = response;
}
return result;
}
async getAccessToken(){
console.log("Getting access token...");
let accessToken = await getToken(); //Returns a Promise
this.token = accessToken;
console.log("Got the token!");
return Promise.resolve(true);
}
問題は、getAccessToken関数内のgetToken()から始まりました。これはpromiseを返す非同期関数です。つまり、応答を待ちません。問題ありません。しばらくお待ちください。問題なく動作します。
ただし、getAccessToken()がgetToken()の終了を待機している場合でも、getData()はgetAccessToken()がgetToken()の待機を終了するのを待機しません。解決?Promiseを返し、getData()内で待機しました。しかし、私はそれを動かしただけで問題を解決しませんでした。
現在、getData()は、リクエストを実行する前にaccessTokenが終了するのを待機していますが、step1、step2、およびstep3は待機していません。ずっと約束を返し、すべての関数を待つという解決策はありますか?私はそれを行うためのよりクリーンな方法があり、実際に待つ必要がある場所を待つだけで、すべてが停止し、それが完了するのを待つことを願っています。
それを行うためのクリーンな方法はありますか?ベストプラクティスは何ですか?
これは私が望む出力です:
これは私が得る出力です:
ずっと約束を返し、すべての関数を待つという解決策はありますか?
はい(ただし、あなたがそれを行う必要はありませんのでご注意明示的にあなたが持っているようにgetAccessToken
、より下の、)。関数が非同期関数の結果に依存している場合、その関数も非同期である必要があります。これはずっと泡立ちます。
必要に応じてmainFunction
処理するstep1
、step2
とstep3
順番に、彼らは、非同期の結果に依存し、それらは非同期でなければならない、とmainFunction
非同期でなければなりません(と、それを使って何が非同期でなければなりません):
async function mainFunction() {
console.log("mainFunction start");
await step1();
console.log("step1 done");
await step2();
console.log("step2 done");
await step3();
console.log("step3 done");
console.log("mainFunction done");
}
async function step1() {
await getData();
}
async function step2() {
await getData();
}
async function step3() {
await getData();
}
async function getData() {
await getAccessToken();
return Math.floor(Math.random() * 1000);
}
async function getAccessToken() {
await asyncStandIn();
}
function asyncStandIn() {
return new Promise(resolve => setTimeout(resolve, 800));
}
// Top level entry
(async () => {
mainFunction();
})().catch(error => {
console.error(error);
});
Re getAccessToken
:async
あなたが持っているようにそれを関数にするだけで、それは常に約束を返すことを意味します。必要はありませんreturn Promise.resolve(true);
。その行を削除するだけです。(ただし、呼び出された関数getAccessToken
がアクセストークンを返さないのは少し奇妙です。)
もっと読む; 私の考えでは、次の重複として質問を閉じることに投票することは正しいことではありませんが、他の人は異なる可能性があります。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加