質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

非同期処理

非同期処理とは一部のコードを別々のスレッドで実行させる手法です。アプリケーションのパフォーマンスを向上させる目的でこの手法を用います。

Q&A

解決済

2回答

2357閲覧

【非同期処理】処理の順番が思い通りになりません。

ryota002

総合スコア20

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

非同期処理

非同期処理とは一部のコードを別々のスレッドで実行させる手法です。アプリケーションのパフォーマンスを向上させる目的でこの手法を用います。

0グッド

0クリップ

投稿2021/03/27 02:27

編集2021/03/27 03:50

前提・実現したいこと

javascriptでTwitter管理システムを作っています。
会員登録を実装中に以下の問題が発生しました。
「createUserData(userData);」の関数の実行完了を待ってから、「monitorLoginStatus()」を実行したいが、順番が逆になる。

signup.jsの抜粋(後半に全文掲載)

js

1twitterOAuth() 2 .then((userData) => { 3 console.log("signup関数の中", userData); 4 createUserData(userData); 5 }) 6 .then(() => { 7 console.log("monitorの前のログ"); 8 monitorLoginStatus().then((loginStatus) => { 9 if (loginStatus) { 10 // location.replace("../../admin.html"); 11 } 12 });

発生している問題・エラーメッセージ

コンソール

signup関数の中 {…省略…}              signup.js:13 monitorの前のログ                  signup.js:17 userId:lOi2qObLIzT4B4oE6DZfpS1qQ0Z2 monitorLoginStatus.js:7 既にユーザーある createUserData.js:30

コンソール(想定している理想の順番)

signup関数の中 {…省略…}              signup.js:13 既にユーザーある createUserData.js:30 monitorの前のログ                  signup.js:17 userId:lOi2qObLIzT4B4oE6DZfpS1qQ0Z2 monitorLoginStatus.js:7

該当のソースコード

signup.js(async/await)

js

1"use strict"; 2 3import createUserData from "../createUserData.js"; 4import twitterOAuth from "../twitterOAuth.js"; 5import monitorLoginStatus from "../monitorLoginStatus.js"; 6 7const twitterSignup = () => { 8 const signUpButton = document.getElementById("signup"); 9 10 signUpButton.addEventListener("click", async () => { 11 const userData = await twitterOAuth(); 12 console.log("signup関数の中", userData); 13 await createUserData(userData); 14 console.log("monitorの前のログ"); 15 monitorLoginStatus().then((loginStatus) => { 16 if (loginStatus) { 17 // location.replace("../../admin.html"); 18 } 19 }); 20 }); 21}; 22 23export default twitterSignup; 24

signup.js

js

1"use strict"; 2 3import createUserData from "../createUserData.js"; 4import twitterOAuth from "../twitterOAuth.js"; 5import monitorLoginStatus from "../monitorLoginStatus.js"; 6 7const twitterSignup = () => { 8 const signUpButton = document.getElementById("signup"); 9 10 signUpButton.addEventListener("click", () => { 11 twitterOAuth() 12 .then((userData) => { 13 console.log("signup関数の中", userData); 14 createUserData(userData); 15 }) 16 .then(() => { 17 console.log("monitorの前のログ"); 18 monitorLoginStatus().then((loginStatus) => { 19 if (loginStatus) { 20 // location.replace("../../admin.html"); 21 } 22 }); 23 }); 24 }); 25}; 26 27export default twitterSignup;

createUserData.js

js

1"use strict"; 2 3const db = firebase.firestore(); 4 5const createUserData = (userData) => { 6 const uids = []; 7 8 db.collection("User") 9 .get() 10 .then((querySnapshot) => { 11 querySnapshot.forEach((doc) => { 12 uids.push(doc.data().uid); 13 }); 14 }) 15 16 .catch((error) => { 17 console.error("Error getting documents: ", error); 18 }) 19 .then(() => { 20 const userRegistration = uids.includes(userData.uid); 21 22 if (!userRegistration) { 23 console.log("新規ユーザー。作る!"); 24 console.log(userData); 25 db.collection("User") 26 .doc(userData.uid) 27 .set(userData) 28 .catch((error) => console.error(error)); 29 } else { 30 console.log("既にユーザーある"); 31 } 32 }); 33}; 34 35export default createUserData;

試したこと

・非同期処理の問題だと思い、aysnc/awaitやthenメソッドなどを使ってみましたがうまくいきませんでした。

補足情報(FW/ツールのバージョンなど)

javascript
node.js v12
firebase Authentication

上手く行ったコード

signup.js

js

1"use strict"; 2 3import createUserData from "../createUserData.js"; 4import twitterOAuth from "../twitterOAuth.js"; 5import monitorLoginStatus from "../monitorLoginStatus.js"; 6 7const twitterSignup = () => { 8 const signUpButton = document.getElementById("signup"); 9 10 signUpButton.addEventListener("click", () => { 11 twitterOAuth() 12 .then((userData) => { 13 console.log("signup関数の中", userData); 14 return createUserData(userData); 15 }) 16 .then(() => { 17 console.log("monitorの前のログ"); 18 monitorLoginStatus().then((loginStatus) => { 19 if (loginStatus) { 20 // location.replace("../../admin.html"); 21 } 22 }); 23 }); 24 }); 25}; 26 27export default twitterSignup;

createUserData.js

js

1"use strict"; 2 3const db = firebase.firestore(); 4 5const createUserData = (userData) => { 6 const uids = []; 7 8 return db 9 .collection("User") 10 .get() 11 .then((querySnapshot) => { 12 querySnapshot.forEach((doc) => { 13 uids.push(doc.data().uid); 14 }); 15 }) 16 17 .catch((error) => { 18 console.error("Error getting documents: ", error); 19 }) 20 .then(() => { 21 const userRegistration = uids.includes(userData.uid); 22 23 if (!userRegistration) { 24 console.log("新規ユーザー。作る!"); 25 console.log(userData); 26 db.collection("User") 27 .doc(userData.uid) 28 .set(userData) 29 .catch((error) => console.error(error)); 30 } else { 31 console.log("既にユーザーある"); 32 } 33 }); 34}; 35 36export default createUserData;

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hentaiman

2021/03/27 02:42

async/awaitなんて見た目通りに書けてめっちゃ簡単だと思うので何かしら些細なミスがあるんでしょう async/awaitで書いたコード載せてみてください
ryota002

2021/03/27 03:01

ご返信ありがとうございます。 コードを追記しました。 ご確認いただけると幸いです。
guest

回答2

0

ベストアンサー

return文がないからじゃないですかね。
似た質問で同様の回答をしたような気がしますし、他の方からも回答されていたような気がしますよ。

関数にはreturn文が必要です。そろそろ覚えてほしいです。

投稿2021/03/27 02:50

Lhankor_Mhy

総合スコア36960

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ryota002

2021/03/27 02:58 編集

## 返信 再三のご回答ありがとうございます。 以下のように、returnをつけているのですが、うまくいきませんでした。 先ほど、回答いただいたreturnに関しては、次のthenや関数の返り値があったので、それで上手くいきました。 今回に関しては、返り値がないものだったので、また違う問題なのかと考えました。 同じポイントのミスでしょうか。 何度も回答いただき本当にありがとうございます。 ```js "use strict"; import createUserData from "../createUserData.js"; import twitterOAuth from "../twitterOAuth.js"; import monitorLoginStatus from "../monitorLoginStatus.js"; const twitterSignup = () => { const signUpButton = document.getElementById("signup"); signUpButton.addEventListener("click", () => { twitterOAuth() .then((userData) => { console.log("signup関数の中", userData); createUserData(userData); return; }) .then(() => { console.log("monitorの前のログ"); monitorLoginStatus().then((loginStatus) => { if (loginStatus) { // location.replace("../../admin.html"); } }); return; }); }); }; export default twitterSignup; ```
ryota002

2021/03/27 03:25

Lhankor_Mhyさんより 「then()のハンドラ関数がPromiseではないものを返す場合、then()は解決済みPromiseを返します」 MDNより 「他の pending 状態の Promise オブジェクトを返した場合、 then によって返された Promise の解決/拒絶は、ハンドラーによって返された Promise の解決/拒絶結果に依存します。また、 then によって返された Promise の解決値は、ハンドラーによって返された Promise の解決値と同じになります。」 という記載を参考にして、以下のように書いてみましたが同様にうまくいきませんでした。 thenチェーンで記載すれば、上から順番に、完了てから次のthenに行くものだと認識していました。 そもそもこの認識が間違いなのでしょうか。 ``` signUpButton.addEventListener("click", () => { twitterOAuth() .then((userData) => { console.log("signup関数の中", userData); return createUserData(userData); }) .then(() => { console.log("monitorの前のログ"); monitorLoginStatus().then((loginStatus) => { if (loginStatus) { // location.replace("../../admin.html"); } }); }); }); ```
Lhankor_Mhy

2021/03/27 03:29

createUserData(userData) の戻り値を確認してみてください。Promise ですか?
ryota002

2021/03/27 03:48

確認したところ、createUserData(userData) の戻り値は設定されていませんでした。 故に、以下の中身がpromiseではなかったから、次のthenにいってしまったということですね。 ``` .then((userData) => { console.log("signup関数の中", userData); return createUserData(userData); }) ``` ここまで理解したことをまとめると、以下のような内容であっていますでしょうか。 ・thenでは基本returnで返り値を次に返す必要がある。 ・返り値がpromiseなら解決/拒絶まで処理を完了させてから次に渡す ・返り値がpromise出ない場合は、promiseの解決/拒絶の処理結果は待たず、次のthenなどの処理に進む 何個もの質問に答えていただき本当にありがとうございます。
ryota002

2021/03/27 03:52

createUserData(userData)の戻り値をpromiseになるようにコードを変更しました。 共有したく質問本文の末尾に追記しました。 ありがとうございます。
guest

0

同期処理にすれば良い。

投稿2021/03/27 02:34

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ryota002

2021/03/27 03:28

ご回答ありがとうございます。 ネットワーク通信を伴う処理を同期処理として記載するにはどのような書き方をすれば良いのでしょうか?
退会済みユーザー

退会済みユーザー

2021/03/27 03:38

C#ならWait()とか付ければいい。 Javascriptでも似たような機能があると思うよ。
soi013

2021/03/30 12:28

ネットワーク通信は同期処理にすべきでないし、C#でWait()を呼ぶのは99%間違った使用方法です。
退会済みユーザー

退会済みユーザー

2021/03/30 18:52

それは速度を重視する場合な。 エラーさえ起こらなければ速度はどーでもいい場合はWait()が一番手っ取り早い。 余計な開発費を膨らませる必要はない。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問