TypeScript 非同期処理を一気通貫で同期処理として約束(Promise)させる

はじめに - Javaエンジニアの苦悩。JavaScriptの非同期処理にはまる -

JavaScriptの非同期処理、await を書いているのになぜかスルーされる……。そんな経験はありませんか?

わたしは数年前、Javaアプリケーション(アプレットだけど)をTypeScriptに移植する際、
この『止まらない非同期』に数週間も頭を抱えました。
結論から言うと、非同期処理を同期処理のように動かすには、
最下層から最上層まで**『一気通貫』で約束(Promise)を一気通貫で繋ぎ切る必要がありました。

今回の記事は、私が泥臭い試行錯誤の末にたどり着いた、非同期リレーの鉄則を共有します。

状況とJavaプログラマからの感覚

JavaからJavaScript(実際にはTypeScriptだけど)に書き換えをしていくとき、
通信処理部分が非同期処理になる。という話はインフラチームからは聞いていました。

現状、Javaでは同期処理となっているので、その通りにする必要がありました。
その解決策として、Promise(約束)を知りました。

その当時の各サイトの情報や、他チームのソースコードを見て真似て書いてみました。

まずは、サーバー通信処理への部分イメージ


function サーバー通信を待つ関数() {

	return new Promise((resolve, reject) => {

		// 1. 通信を投げる
		通信処理を投げる();

		// 2. 終わったかどうかを定期的にチェックする(ポーリング)
		const timer = setInterval(() => {
			if (通信成功した?) {
				clearInterval(timer);
				resolve("成功データ");
			} else if (タイムアウトした?) {
				clearInterval(timer);
				reject("エラー");
			}
		}, 100); // 100ミリ秒ごとに確認

	});
}

【Javaエンジニアの視点で】

実際には、手探り状態で必死でした。
「Promiseというものを使えばいいらしい」
「setIntervalで監視すれば待てるはずだ」……。
慣れないTypeScriptと格闘しながら、ようやく書き上げたこの最下層の関数。

「これだけロジックを組んだんだ。
これでもう、Javaの同期処理と同じように、
この関数を呼んだところでプログラムは一旦止まり、
データが返ってくるのを待ってくれるはずだ」

そう、一番下(最下層)さえ「待てる構造」に作り替えれば、
上層階のプログラムたちは何も知らなくても恩恵に預かれると、
本気で信じていたのです。

上層部は「約束」を無視して走り去っていく。。。

最下層プログラムを作りきり、
上位メソッドは現行Javaのロジックを移植して、いざ、処理を呼び出してみました。

フロントエンドは変わっているので、
A(GUI)→B→C(最下層の共通処理)でいうと、Bの部分は移植でいけました。
Aはもちろん新規作成です。

Javaエンジニアの感覚なら、通信が終わるまで止まってくれるはずです。

Bの通信処理


export class B {

	public 通信処理B():返信データ {
・・・
		// Cが終わるまでここで「待つ」
		let 返信データ = C.サーバー通信を待つ関数();

		return 返信データ;

	}

}

Aのイベント処理(GUI)

イメージとしてはBと変わりはありません。


export class A {

	public イベント処理A() {
・・・
		// Bが終わるまでここで「待つ」
		let 返信データ = B.通信処理B();

		// ここでようやく本物のデータを使って貼り付けができる
		this.データ貼り付け処理(data);

	}

}

これが止まらないんです。
データ貼り付け処理が先に動いてしまうんです。
ここからなぜなぜ地獄にハマりました・・・汗。

解決:最上層から最下層まで「一気通貫」で繋ぎ切る

結論から言うと、JavaScript/TypeScriptの世界で同期処理を実現するには、
**「バトン(Promise)を受け取る全員が、前の走者を待つ(await)」**
というルールを徹底するしかありません。

一箇所でも await を忘れたり、async を抜かしたりすれば、
その瞬間に「一気通貫」は崩壊し、プログラムは走り去ってしまいます。

Bの修正:リレーの中継地点

まずは中間の「B」です。 ここが一番の盲点でした。
自分も「約束(Promise)」を返すように宣言し、下層の結果をしっかり待ちます。


export class B {

	// 1. asyncを付けて「非同期(約束を返す)メソッド」であることを宣言
	// 2. 戻り値を Promise<返信データ> に包む
	public async 通信処理B():Promise<返信データ> {
・・・
		// 3. await を付けて、Cが終わるまでここで「止まって待つ」
		let 返信データ = await C.サーバー通信を待つ関数();

		return 返信データ;

	}

}

Aの修正:一気通貫のゴール地点

そして最上層の「A」です。
ここも同様に「待ち」の姿勢を入れなければなりません。


export class A {

	public async イベント処理A() {
・・・
		// 4. ここでも await。Bが結果を持ってくるまで次の行へ行かせない!
		let 返信データ = await B.通信処理B();

		// 5. ここでようやく、本物のデータ手に入れることができ、データ貼り付けができる
		this.データ貼り付け処理(data);

	}

}

まとめ:数週間かけて分かった「一気通貫」の正体

Javaエンジニアの私にとって、
最大の誤算は**「一番下が待てば、上も勝手に待つだろう」**という思い込みでした。

JavaScriptの世界はシビアで厳しいものでした。
「待ってほしいなら、全員が『待つ(await)』と宣言し、
バトン(Promise)を繋ぎ続けなければならない」。

この「一気通貫」の鎖さえ完成すれば、
非同期処理はまるで魔法のように、
Javaの同期処理と同じような顔をして動いてくれるようになります。

もし、あなたの await が無視されているなら、
どこかでその鎖が切れていないか、
数珠つなぎを一から辿ってみてください。

注意! たとえAとCが完璧でも、
中間のBが await を一回忘れるだけで、
Aの手元にはまた「空っぽの箱(Pending状態のPromise)」が届くことになります。

参考情報

Promise を使う(Promise チェーンの解説)
https://developer.mozilla.org/ja/docs/Web/JavaScript/Guide/Using_promises

「async/await」の公式解説
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/async_function

#TypeScript #async-await

シェアしていただけるとうれしいです。

JavaFXシューティングゲーム編 - EXE起動できるようにしてみました!!!!!

虎の巻のページにEXE起動に取り組んだ企画を追加しました!

https://kinchannn.jp/java-programing-toranomaiki/

Javaの環境ない人も動くはずです。
下にモジュールを公開するので試してみてください!

けっこう大変でした~。
JavaFXやJINPUTまで入れ込んでみました。
(JavaをExeにしているページはあるかもしれないけど、ここまではない?かしら?)

モジュールあります!

試してみてくださいね(^^)♪
SKK4_FX_EXE.zip

Youtube公開動画
https://youtu.be/pTQt_pPXgqc

Javaコンパイルしたモジュールをexe化してみる(1)Javaがexe化するに至った経緯を振り返る。
Javaコンパイルしたモジュールをexe化してみる(2)EXE化への「5段構え」の工程
Javaをexe化してみる(3)環境構築とJMODSを追加する
Javaをexe化してみる(4)バッチファイルで自動化しパッケージングする

シェアしていただけるとうれしいです。

わたしのサイトも狙われた。国内IPからの執拗なログイン試行とその対策(ブルートフォース攻撃)

あなたのサイトにも忍び寄る悪意

最近、サイトの見直しをいろいろと行っているのですが、
その時に気づいたのが、覚えのないログイン試行。

11:11から11:18にかけて、300回のログイン試行が行われました。
数秒ごとに行われているので、自動化されたツールから試行されてるっぽいですね。

辞書総当たりでアタックしてきたのかな・・・。
ログから読み取れることは少ないですが・・・。
IPはわずかに変動しています。
ブロックを回避しようとする攻撃側の工夫(分散攻撃)かもしれません。

しかし、わたしのような弱小サイトまで狙ってくるとは・・・。

あまり情報を公開はしたくないですが、
WordPress上で、セキュリティのプラグインを入れて防御しています。

ちなみに、IPアドレスは国内のようで、
事前に乗っ取られてしまったサイトなのかもしれません。

国内IPを介した攻撃は、海外からの直接攻撃を警戒する
セキュリティ設定を潜り抜けるための手口かもしれません。
つまりは、踏み台にされている可能性があります。

踏み台にさせられた、そのサイトにも原因があるかもしれません。
セキュリティは、サイトを運用する人の責任でもあると思います。

乗っ取られないようにするために

自分のサイトが乗っ取られないようにするため、
他のサイトに迷惑をかけないようにするため、
以下はしっかりと対応しましょう。

パスワードは予測可能なものにはしない

辞書攻撃で破られるようなパスワードはやめましょう。

セキュリティ等をかける

WordPressなどではプラグイン等で予防することが可能です。
イメージを見ていただくと、ログイン失敗からロックに変わっています。

ログイン失敗が続いたあと、ステータスが「ロック」に変わっています。
これはプラグインが自動で異常を検知し、攻撃者のアクセスを遮断した跡です。
もしこの対策がなければ、数万回の試行を許し、今ごろサイトは乗っ取られていたかもしれません。

その他のサイトでも、なにかしらの予防を施すことが肝要です。

最新モジュールを保つ

悪意のある人はセキュリティホールを狙ってアクセスする可能性があります。
最新化を保つことが、サイト管理者にとって大事な作業になります。

推測されやすいユーザー名は避ける

「admin」や「サイトドメイン名」などをそのままユーザー名に使うのは危険です。
攻撃者はまずこれらを試してきます。
ログインURLの変更なども含め、入り口を特定させない工夫も効果的です。

多要素認証を利用する

「多要素認証」を利用している場合、仮にIDおよび1つ目のパスワードを不正利用されても
次のログイン行為を破られないかぎりは、不正ログイン防止に効果があります。

自分のサイトなので、多要素認証は有効となりますが、

少し話がずれてしまいますが(こことは話が少しずれてしまいますが)、
他のサイト等を訪問している際は、
フィッシングサイトなどでサイト自体が詐称されている場合があります。
その際はふたつ目のログイン行為も破られる可能性があり、注意が必要です。
(多要素認証といえど、必ずしも安全ではないことに注意が必要です。
  万能薬ではないことはお伝えしておきます)

参考ページ

不正ログイン対策特集ページ - IPA 情報処理推進機構

https://www.ipa.go.jp/security/anshin/measures/account_security.html

IPスプーフィング/DDos攻撃 - 攻撃を受けている可能性。あなたも受けているかも。 - きん たろう のページより

https://kinchannn.jp/2021/03/03/attack/

と、書いてるうちにも、フィッシングメール・・・汗

君のメール自体が詐欺メールなんだけど・・・

シェアしていただけるとうれしいです。

共通編の見直しも実施しました(Java25&JavaFX25対応)Javaでゲームを作ろう

https://kinchannn.jp/javagame_common/

お正月休みの終わりが近くなってきた・・・汗。
もう休もう・・・(笑)

Java25&JavaFX25の対応が終わりました。
(他にはないことを祈る・・・汗)
各ゲームをJavaの最新LTSバージョンで動かしてみるのと、
共通編の修正と、大変でした。

今にして思えば、共通編は外出しにしておいて(本編からは切り離しておいて)
よかったと思っています。
全部の本を修正すると思ったら、発狂しそうです・・・汗汗汗。

とりあえずは、やった感があるので、よかったー。
もう少し早めにできるとよかったけど、なかなかねー。。。

Java25対応版ソースはこちら♪

Javaでゲームを作ろう

https://kinchannn.jp/javagame/

The Java 使いこなす

https://kinchannn.jp/thejava/

動作確認に、いろいろとゲームを少しだけやりました~。
本人が苦笑してしまう出来だなー。今思い出しても。

Javaでゲームを作ろう3- JavaFXシューティングゲーム編 -ダイジェスト版
https://youtu.be/pTQt_pPXgqc

Aki2氏とのすったもんだもいろいろと思い出せて面白いものです(笑)。

シェアしていただけるとうれしいです。

Java25&JavaFX25対応をおこないました。全てのモジュール、対応完了!

おはようございます。きんです。

Java25&JavaFX25対応をおこないました。

現在の最新バージョン、LTSである25.0.1にて動作確認を行いました。
Java、JavaFX、ともに同じバージョンになります。

一部、sta.batとj.batの入れ替えを行っています。
ソースもわずかですが、修正を行いました。
(一部、コンパイルエラーになった部分のみ対応)
HPに置いてあるzipファイルについては、更新を行っています。

ココナラでの活動もあり、最新化しておく必要性もあったので、対応した。
というのが、正直なところでありますが、
現状のままだと、動かないところもあったので、最新化できてよかったと思っています。

ちなみにまだココナラでの活動(サポート)はまだとなりますが、
よければご利用くださいね~♪

↓↓↓ココナラのわたしの出品ページ↓↓↓
https://coconala.com/services/3999646?ref=top_histories&ref_kind=home&ref_no=1

新しい年がはじまって二日目。
今年もがんばるよー。がんばりましょう♪

本業の方は、また来年度から忙しくなるかも?
さてー、どうなるかなー・・・(--。。。

わたしのサイトもよろしく!
https://kinchannn.jp

The Java 使いこなす についても、約半日遅れで修正が完了しています。
(2026/01/02 19:39)

シェアしていただけるとうれしいです。

明けました。がんばっていきましょう。おたがいにー(*^^)ノ

新年になりました。

おめでとう。
とはいう気になりませんが、自分のできる範囲で今年もがんばっていきましょう。

世界は混沌としている
と思っています。

できれば安寧に暮らしたい。
そのように思っています。

自分のできる範囲でやっていきましょう。
お互いを尊重し、認め合い、意見を聞き、自分の意見も伝え、よりよい道を模索していきましょう。

シェアしていただけるとうれしいです。