記事執筆の理由
非同期という言葉、ビミョーにわかりづらい。
ちゃんと理解しようとした(今更?)
まず、同期と非同期は、なんの話?
単純に、処理の順序の話らしいが、
自分は待機の話と理解したほうがわかった。
同期とは
処理の順序が固定であるということ。
待機がない。
朝の同期処理(固定順、対木梨)
console.log("1: 歯を磨く");
console.log("2: 顔を洗う");
console.log("3: 朝ごはんを食べる");
非同期とは
- 「ある処理が終わるのを待たずに、次の処理に進む」→待機がある
-
あくまで動く処理は一つ
→並列とは違う - 待機とセットで、再開 がある
コードでいったら
await は 「待機の開始地点」 であり、
処理を一時中断して、Promiseの完了を待つことを意味する
1: start
↓
2: await ← ★処理中断の意味(この時点で Promise で pending)
↓
3: promise resolved ← Promiseが解決したら、次(fulfilled)
↓
4: after await ← awaitが再開される
参考コード
ts
async function taskA() {
console.log("A1: start");
await new Promise((resolve) => {
setTimeout(() => {
console.log("A2: timer done (resume)");
resolve("result");
}, 2000); // ←★この2秒の間、taskAは中断される
});
console.log("A3: after await"); // ←★ここで再開される
}
async function taskB() {
console.log("B: taskB runs during taskA's await");
}
async function main() {
console.log("main: start");
// taskAの非同期開始(ただし中断ポイントありのため、止まる。)
const aPromise = taskA();
//taskBの非同期開始
await taskB();
//await taskB() の await = taskB() が返す Promise の「完了(fulfilled)」を待っている
//が、Promiseがないので即時実行して終わり
await aPromise; // taskAの終了を待つ
console.log("main: done");
}
main();
出力
main: start
A1: start
B: taskB runs during taskA's await
A2: timer done (resume)
A3: after await
main: done
rust
use tokio::time::{sleep, Duration};
async fn task_a() {
println!("A1: start");
sleep(Duration::from_secs(2)).await; // ★ここで中断(非同期の待機)
println!("A2: resumed after await");
}
async fn task_b() {
println!("B: runs while task_a is sleeping");
}
#[tokio::main]
async fn main() {
println!("main: start");
let a = task_a(); // 非同期タスクを作る(まだ実行されていない)
// 0.5秒後に task_b を走らせる(task_a の sleep 中)
tokio::spawn(async {
sleep(Duration::from_millis(500)).await;
task_b().await;
});
a.await; // task_a を待つ(再開される)
println!("main: done");
}
出力イメージ
main: start
A1: start
B: runs while task_a is sleeping ←← task_a の sleep 中に実行される
A2: resumed after await
main: done