【統合版アドオン】part-6│ScriptAPIで出てくる非同期処理の話を。

スポンサーリンク

初めに

どうも餅わらびすとです。この記事では究極の機能、ScriptAPI(gametestとも言う)でたまに出てくる非同期処理について軽く解説します。

軽く、というとなんだとなるかと思いますが非同期処理は自分も解説出来るほどの知識ではないんですよね。なら解説とか言うなってなるるのでメモぐらいの感覚で書いていきます。メモぐらいの感覚で読んでください。間違っている部分があったらバンバン教えてください。

~前回~
https://minecraft-mcworld.com/75095/

非同期処理ってなんやねん

非同期処理とは、やってる処理を順にこなさなくていいよ的な処理の形です。デフォでは同期処理っていう上から順に実行される形になっています。
分かりやすく言うと、例えば山さんと川さんがいるとします。山さんは、部屋の掃除をしたいけれども川さんの読んでいる本を借りたいです。
ここで、川さんが本を読み終わるのを待ち、その後に掃除をします。これが同期処理。

%E5%90%8C%E6%9C%9F%E5%87%A6%E7%90%86.png

しかし、これでは待つ時間が無駄になってしまいます。ここで非同期処理。
川さんが本を読んでいる間に掃除をします。そして掃除をしている間に川さんは本を読み終わるので掃除が終わったらすぐに本を読めます。

%E9%9D%9E%E5%90%8C%E6%9C%9F%E5%87%A6%E7%90%86.png

効率的!
って話です。
時間がかかる処理は別でまたやっていて他の処理もやってるよ的な。

どう使うの?

functionの前にasyncを付けることで非同期処理の関数になります。

//ノーマルの関数の場合
async function example() {...}

//アロー関数の場合
const example = async () => {...}

この中では、Promiseやawaitといった処理の決め事を使えます(Promiseはインスタンス化すればasyncじゃなくとも使える)。

Promise

Promiseはいくつかの状態があり、よく使うのが解決(resolve)です。

new Promise(resolve => {
resolve();
});

という形で、newで生成されたPromiseを解決した状態に出来ます。

Promise.resolve();

では解決されたPromiseが返ってきます。

解決される際resolveの()の中にデータを入れて解決されたときのデータを渡す的なことも出来ます。

ちなみに、async functionはPromiseを返すようになっています。returnがresolveみたいな役割してます

await

awaitは、右にPromiseが置かれたときに、そのPrimiseが解決されるまでasync functionの処理を一時停止する、というものです。

async function example() {
await new Promise(resolve => {
system.runTimeout(resolve, 20);
});
world.sendMessage("hello!");
}

例えばこのコードだと、system.runTimeoutで20ティック(1秒)後に解決されているので、この関数を実行した1秒後worldにhello!と送信されるわけです。

実際どんな時使われるのか

元々のScriptAPIのメソッドにも非同期処理が使われているものがあります。
例えば、DimensionやEntityのrunCommandAsync。これは実行した時処理の完了を待たずして次の処理に移ります。

ActionFormDataなんかのshowもそうです。これはボタンが押されたとき、Promiseのオブジェクトが返ってきます。
何回か前のカスタムUIの話で、thenの話が出てきましたね。これはそのとき言ったようにPromiseに実行できるものなのです。
thenは、Promiseが解決された際にresolveで渡された値をそのまま引数のコールバック関数の第一引数に入れます。
.show(player).then(re => {…});とはそういうことなんですね!

showでデータが返ってくるならば勿論他の書き方だって出来るわけです。
例えばこういう。

async function showForm(player) {
const form = new ActionFormData();
form.button("ボタン");
const re = await form.show(player); //ボタンが押されてデータが返ってくるまで以下処理を一時停止
if (re.selection === 0) world.sendMessage("ボタンを押したぞ!");
}

ネストが深くならず幸せ!

まあこう非同期処理というのは色々出来るわけです。
難しいけど便利ですね!みんなも使おう非同期処理!

最後に

ここまで読んでくださりありがとうございました!役に立ったと思ってもらえたら嬉しいです。

なにか質問があるときはこちらのディスコードサーバーから受け付けています。どんな人も大歓迎!

それでは良いアドオンライフを!

※投稿記事に含まれるファイルやリンクにより発生した被害についてクラフターズコロニーは責任を取りません
投稿通報

コメント

コメント通報