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

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

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

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

Q&A

解決済

2回答

630閲覧

JS 非同期 awaiについて

2_34_koki

総合スコア67

JavaScript

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

0グッド

1クリップ

投稿2020/04/29 07:03

awaitの挙動が理解できないのですが、なぜ下記のようなことが発生するのでしょうか?

router.post("/", async (req, res, next) => { const token = req.headers.token; const payload = req.body.payload; const decoded = await CheckIdToken(token).catch(console.log); const uid = decoded.uid; //ここから CreateWork(uid, payload, next); console.log("LITSTENEND CREATEWORK"); return res.json({ status: 200, }); }); async function CreateWork(uid, data, next) { console.log("================ SEARCH ================="); const client = await pool.connect(); var user = await client .query("SELECT * FROM USERS WHERE uid = $1", [uid]) .catch(next); const id = user.rows[0].id; //こいつが後から出でくる。 console.log("================ continue ================="); var sql = "INSERT INTO WORKS (user_id, title, detail, github, deploy, thumbnail) values ($1, $2, $3, $4, $5, $6)"; const values = [ id, data.title, data.detail, data.giturl, data.workurl, data.thumbnail, ]; let result = await client.query(sql, values); sql = createSql(data.tags, result.rowCount); client.query(sql); console.log("END CREATEWORK"); } コンソール // ================ SEARCH ================= [1] LITSTENEND CREATEWORK [1] ================ continue ================= [1] END CREATEWORK

ここで疑問なのがなぜawaitで非同期関数を同期的に振る舞っているのにもかかわらず、こののようなことが発生するのでしょか?
一応、下記のようにすると同期的にはなります。

await CreateWork(uid, payload, next);

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

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

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

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

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

guest

回答2

0

async関数と言っても、実態としては単なる「Promiseを返す関数」でしかありません。そして、awaitの役割は、「awaitの後に書かれた式がPromiseだった場合、そのresolveを待つ」ことです。

つまり、async関数をawaitせずに呼んだ場合、Promiseを返すだけになって、次の行へそのまま進んでしまいます。受け取る側のawaitは「一応」ではなく、非同期実行を行うために必須のものです。

投稿2020/04/29 07:30

maisumakun

総合スコア145201

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

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

2_34_koki

2020/04/29 10:06

すいません。一つ疑問あのですが、下記のようなコードを実行した時に、 結果がBAAAAABCになりました。 async function A(){ console.log("A"); console.log("A"); console.log("A"); console.log("A"); console.log("A"); } async function B(){ console.log("B"); A(); console.log("B"); } function C() { console.log("C"); } B(); C(); Bはasyncにっているのにもかかわらず、中身を全て実行しています。 この場合だと、なぜ次の行にステップされないのかわからないです。
guest

0

ベストアンサー

Promise の結果(resolver または rejectorを実行することで処理が終了)を待つのが await です。

フロー制御の標準となった Promise も実装は非同期処理です。このため 結果を待たずに次の行を処理します(console.log("LITSTENEND CREATEWORK");が先に実行される理由)。

Promise は .then() .catch() でコールバック関数を与えるという独特な実装が特徴になります。
メソッド名 then をGoogle翻訳すると「その後」と訳されるように、メソッドチェーンで書くと同期的で読みやすいという特徴を持っていますが、非同期処理に過ぎないため、複数の Promise 化された処理を複雑に構成するとコールバック地獄に陥ることに変わりなかったのです。

後に await という構文が登場し、Promise の結果を「待つ」実装のおかげで、完全な同期的記述が実現できるようになりました。
await は コールバックを書かずに済む 糖衣構文 とも言えそうです。

投稿2020/04/29 07:56

AkitoshiManabe

総合スコア5434

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.47%

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

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

質問する

関連した質問