0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Async, Awaitの備忘ログ

Last updated at Posted at 2025-10-17

はじめに

原理原則はまだまだわかりません。
なので、やってみたor検証的な側面が強いです。

非同期とは

同時に進行せず、独立して実行される。されること

"非同期である"を決定づける要素

  1. Promseを返す関数
  2. asyncで定義された関数←asyncで定義された関数は必ずPromiseを返す
  3. callbackを受け取る関数: 省略

async/awaitをつけた場合とつけない場合

どこかのwebサーバーにrequestを送る処理を想定する

// 何もつけない
const doRequest1 = () => {
	const res = axios.get("https://example.com")
	console.log("doRequeset1: I got response")
	return res
}

// asyncとawaitをつける
const doRequest2 = async () => {
	const res = await axios.get("https://example.com")
	console.log("doRequest2: I got response")
	return res
}

何が違うの?

  • await以降の処理の実行タイミングが違う
    • doRequest1の場合は、requestが実行された直後にconsole.log()が実行される
    • doRequest2の場合は、requestのresponseが来た後にconsole.log()が実行される

※別の角度から捉えると、doReqeust1はaxiosのPromiseを返してお役目を終了している。


引っかかりやすいケース

res1 = doRequest1()
res2 = doRquest2()
console.log("A")
console.log("B")
console.log("C")

これは両方のパターンのログもいつ出てくるかわからない
asyncとawaitで囲ったからといってdoRequest2()の処理は同期的にならない

では、doRequest2は裏で何をしているか?

axiosでexmaple.comにrequestするで
→ ん、awaitついとるやん。一旦、Promiseを返しとくわ
→ (get request完了)
→ よっしゃ続きの処理やるか、logを出力して
→ resをreturnね。さっき返したPromiseに渡しとくわ

つまり、res2の面倒を最後まで見ることができるようになっているだけ。
※ res1の方はPromiseのobjectを作り出して処理を終了している


responseを受け取ってから処理をしたい

その場合は以下の様になる

const main = async () => {
    res2 = await doRequest2()
    console.log("A")
    console.log("B")
    console.log("C")
}

※ awaitを使うにはtopレベルでasyncによりwarpする必要がある

asyncとawaitをつけるメリット

エラーハンドリングができるようになる

const doRequest1 = () => {
	try {
		const res = axios.get("https://example.com")
		console.log("doRequeset1: I got response")
		return res
	} catch (error) {
		console.log("Error in doRequest1")
	}
}

これはrequestのerrorを捉えれない。
doReqeust1()自体はaxiosのPromiseを一瞬で返して処理は終了されるため

const doRequest2 = async () => {
	try {
		const res = await axios.get("https://example.com")
		console.log("doRequeset2: I got response")
		return res
	} catch (error) {
		console.log("Error in doRequest2")
	}
}

これはOK。
awaitを書くことで、Promiseの完了を関数内で捉えることができる。
よって、resquest中におきたerrorは関数内のtry-catchで補足される

テストができる

describe('test doRequest1', () => {
  it('get response successfully', () => {
	  res1 = doRequest1()
  });
});

これは絶対成功する。
不適切なrequestをしたとしても。
axiosのrequest処理の完了を待たずしてtestが終了するため

describe('test doRequest2', () => {
  it('get response successfully', async () => {
	  await doRequest2()
  });
});

これは大丈夫。

  • request処理の終了が終わってからテストが終了するため
  • テストフレームワークがasync関数の場合、
    返されたPromiseの解決を待ってからテスト完了とするため。

awaitのもう一つの役目

Promiseの開封作業をしている

const res2 = await doRequest2() // Promise<fulfiled>の中身を開封してresに突っ込む

// 同じことをやろうとすると
const Promise1 = doRequest1()
Promise1.then( response => { // resopnseはPromise<fulfiled>の中身。名前は何でもOK
	const res1 = response
})

callback地獄のsample

// 複数のリクエストがある場合...

doRequest1()
.then(() => {
    return doRequest2()
})
.then(() => {
    return doRequest3()  
})
.then(() => {
    doSomething1();
    doSomething2();
    doSomething3();
})


await doRequest1()
await doRequest2()
await doRequest3() 
doSomething1(); // 全部完了後に実行 
doSomething2(); // 全部完了後に実行 
doSomething3(); // 全部完了後に実行

感想

また学んだことがあれば追記していく予定です。
とりあえず最低限のポイントは理解できたと思ってます。

0
0
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?