まえがき
javascriptは、たまにブラウザの開発ツール内コンソールに打ち込んだり、userscriptとして使うくらいです。
教養がありません。
そして非同期処理についてよくわかりません。
もともと、sleep関数の実装を海外サイトのどこかで拾って、それを使いまわしていたのが機能しないことがあり、モヤモヤしていました。
そのモヤモヤを少しでも軽くするために動作確認しようと思ったのが、今回投稿した内容の実験まがいを始めた背景です。
これまでやったことをまとめておいて、またモヤモヤしたときに今回中途半端で終わったところからまた実験まがいを進めるために投稿しました。
本文
codesandboxにて、javascriptのvanillaテンプレートからプロジェクトを作成しました。
そして、そのプロジェクトのindex.jsに下記のコードを書いて実行しました。
const n = 3;
const sleep = (millisecond) =>
new Promise((resolve) => setTimeout(resolve, millisecond * 1000));
function func1_callby_async_function() {
console.log("func1_callby_async_function");
}
function func2_callby_async_function() {
console.log("func2_callby_async_function");
}
function func3_callby_async_function() {
console.log("func3_callby_async_function");
}
function func1_callby_not_async_function() {
console.log("func1_callby_not_async_function");
}
function func2_callby_not_async_function() {
console.log("func2_callby_not_async_function");
}
function func3_callby_not_async_function() {
console.log("func3_callby_not_async_function");
}
async function async_function() {
console.log("start async_function.");
func1_callby_async_function();
await sleep(n);
func2_callby_async_function();
await sleep(n);
func3_callby_async_function();
await sleep(n);
console.log("half async_function. ↑sleep ↓notsleep");
func1_callby_async_function();
func2_callby_async_function();
func3_callby_async_function();
console.log("end async_function.");
}
function not_async_function() {
console.log("start not_async_function.");
func1_callby_not_async_function();
sleep(n);
func2_callby_not_async_function();
sleep(n);
func3_callby_not_async_function();
sleep(n);
console.log("half not_async_function. ↑sleep ↓notsleep");
func1_callby_not_async_function();
func2_callby_not_async_function();
func3_callby_not_async_function();
console.log("end not_async_function.");
}
async function work_one_notasync() {
not_async_function(); //こちらはどうやらsleepが機能していない。
//await async_function();//こちらはsleepが機能する
}
async function work_one_async() {
//not_async_function(); //こちらはどうやらsleepが機能していない。
await async_function(); //こちらはsleepが機能する
}
async function work_two_order_is_async_to_notasync() {
await async_function(); //こちらはsleepが機能する
not_async_function(); //こちらはどうやらsleepが機能していない。
}
async function work_two_order_is_notasync_to_async() {
not_async_function(); //こちらはどうやらsleepが機能していない。
await async_function(); //こちらはsleepが機能する
}
//# 疑問
/*
asyncとawaitが同機能するのか調べてみる。
1. asyncやawaitのない関数においては非同期関数sleep(拾い物)は機能するか?
2. asyncの付いた関数内部においては上から順に実行されないのではないか?
3. awaitとawaitを付けない関数呼出しが混在した関数内では、処理の順序はどうなるのか。
┗e.g.
┗ awaitを付けない関数呼び出しだけ並列に実行される?
┗ awitを付けた関数呼び出しだけ直列に実行される?
┗ awaitを付けた関数呼び出しを先に記述していても、awaitを付けない関数呼び出しが先に実行される?
*/
//## 観点
//1. 上から下へという実行順序になっているか?
//2. sleepが機能しているか?(目検で3秒程度の間をおいてlogが出力されているか見る)
//## 実験とその結果
//### 実験1
//work_one_notasync();
//#### 結果
//上から順に実行される && sleepが機能しない
//### 実験2
// work_one_async();
//#### 結果
//上から順に実行される && sleepが機能する
//### 実験3
// work_two_order_is_async_to_notasync();
//#### 結果:サマリ
//最初に、asyncが実行された。上から順に実行される && sleepが機能した
//次に、notasyncが実行された。上から順に実行される && sleepが機能しなかった
//#### 結果:コンソールの最終出力
// start async_function.
// func1_callby_async_function
// func2_callby_async_function
// func3_callby_async_function
// half async_function. ↑sleep ↓notsleep
// func1_callby_async_function
// func2_callby_async_function
// func3_callby_async_function
// end async_function.
// start not_async_function.
// func1_callby_not_async_function
// func2_callby_not_async_function
// func3_callby_not_async_function
// half not_async_function. ↑sleep ↓notsleep
// func1_callby_not_async_function
// func2_callby_not_async_function
// func3_callby_not_async_function
// end not_async_function.
//### 実験4
work_two_order_is_notasync_to_async();
//#### 結果:サマリ
//最初に、notasyncが実行された。上から順に実行される && sleepが機能しなかった
//次に、asyncが実行された。上から順に実行される && sleepが機能した
//#### 結果:コンソールの最終出力
// start not_async_function.
// func1_callby_not_async_function
// func2_callby_not_async_function
// func3_callby_not_async_function
// half not_async_function. ↑sleep ↓notsleep
// func1_callby_not_async_function
// func2_callby_not_async_function
// func3_callby_not_async_function
// end not_async_function.
// start async_function.
// func1_callby_async_function
// func2_callby_async_function
// func3_callby_async_function
// half async_function. ↑sleep ↓notsleep
// func1_callby_async_function
// func2_callby_async_function
// func3_callby_async_function
// end async_function.
//# 疑問に答えてみる
/*
1. asyncやawaitのない関数においては非同期関数sleep(拾い物)は機能するか?
→ 機能しなかった。機能させるためにはasync,awaitが必要。
→ 非同期関数Aが機能して、非同期関数Bが機能しない、というようなことがあるか?i.e. 今回の実験結果から非同期関数一般について述べることはできないのではないかと思ってる。非同期関数一般について実験するにはどうすればよいか、が今後の課題。
→ ref. 実験1,3,4
2. asyncの付いた関数内部においては上から順に実行されないのではないか?
→ ちゃんと上から順に実行される。
→ ref. 実験4
3. awaitとawaitを付けない関数呼出しが混在した関数内では、処理の順序はどうなるのか。
┗e.g.
┗ awaitを付けない関数呼び出しだけ並列に実行される?
→ awaitを付けない関数呼び出しでも直列に実行された。
→ ref. 実験1,2
┗ awitを付けた関数呼び出しだけ直列に実行される?
→ awaitを付けた関数も付けていない関数も、どちらも直列に実行された。
→ ref. 実験1,2
┗ awaitを付けた関数呼び出しを先に記述していても、awaitを付けない関数呼び出しが先に実行される?
→ awaitを付けている、付けていないに関わらず、どちらも
→ ref. 実験3,4
*/
ちなみに、コード内の「サマリ」部分は、実験1--4の実験対象関数実行部分のコメントアウトを、一つずつ外して実行した結果を目で見て観察した結果を書いています。
(js知らず、変わった言葉づかいしています。e.g. 直列=同期,並列=非同期 的な意味で使っています。)
感想
コード自体の反省としては、もっとシンプルに書きたかったとか、分かりやすい命名をしたかったなと思います。
方法論の反省点のほうが深刻です。
特に何も考えず始めて、何も考えずやっているので、もうちょっと再現性のある試行錯誤と探求を目指します。
今後も改善は続けたいです。
楽しめればいいと無目的にやっています。
しかし、GreaseMonkeyなどで使うために、今後も試行錯誤してより簡単な同期処理用テンプレートを作ることを目指そうかと思います。