木曜日, 12月 18, 2025
No menu items!
ホーム ブログ ページ 5630

「志田彩良ら新ドラマ『スティンガース』おとり捜査班加入!」

ざっくり内容:

ドラマ『スティンガース 警視庁おとり捜査検証室』の概要

2023年7月22日から放送が開始されるフジテレビの新ドラマ『スティンガース 警視庁おとり捜査検証室』。この作品は、警視庁の異端チーム「スティンガース」を舞台にした、オリジナルの爽快コンゲーム・エンターテインメントです。主演は森川葵が務め、彼女の演じる二階堂民子はキレのある魅力的な捜査官です。

新たなキャストの発表

最近、追加キャストとして志田彩良、井内悠陽、杉本哲太の出演が発表されました。彼らは「スティンガース」のメンバーとして、それぞれ異なる背景を持つキャラクターを演じます。

  • 志田彩良(森園はな役): 交通部から異動希望を叶えた新人刑事。美術学校を卒業し、手先が器用な特技を持っています。

  • 井内悠陽(小山内誠役): 総務部から異動、SNSで人気のコスプレイヤー。多彩な衣装の調達能力を持ち、人懐っこい性格が特徴です。

  • 杉本哲太(関口欣二郎役): 忍耐強い性格で、決められた手順を厳守する真面目なキャラクターです。

ドラマのテーマと特徴

このドラマは「おとり捜査」という、日本においてまだ曖昧な制度に真正面から挑む内容になっています。警察の異端チームとしての活躍が描かれることで、緊張感とともにハラハラドキドキの展開が期待されます。

キャストのコメント

各キャストは役柄についてポジティブな感想を述べ、視聴者に楽しんでもらいたいという期待を寄せています。志田は「制服モノに挑戦できるのが嬉しい」とコメントし、井内は「ハラハラドキドキの演出にワクワクしている」と語ります。杉本は「新しい刑事ドラマとして楽しみにしてほしい」と述べています。

放送情報

『スティンガース 警視庁おとり捜査検証室』は7月22日より毎週火曜日21時に放送予定で、初回は15分拡大します。新たな視点で描かれる刑事ドラマに、ぜひ注目してみてください。

編集部の見解:
ドラマ『スティンガース 警視庁おとり捜査検証室』の放送が間近に迫っていますね!おとり捜査という少し特殊であまり知られていないテーマを取り上げることで、視聴者に新たな視点を提供する意図が感じられます。

最近、おとり捜査は特に日本において議論が多いトピックです。実際、犯罪対策としての有効性と倫理的な問題が絡み合っています。このドラマでは、そのグレーゾーンに挑む異端チームの姿が描かれるとのこと。捜査官たちの成長やチームワークがどのように描かれるのか、とても楽しみです。

志田彩良さんが演じるキャラクター、森園はなの背景も興味深いですね。交通部からの異動、加えて舞台芸術の経験を持つ彼女が、おとり捜査にどのように役立つのか。その手先の器用さが捜査に生かされるシーン、きっと見どころ満載でしょう!

井内悠陽さんがコスプレイヤー役を演じることや、杉本哲太さんの「鉄の関口」の特徴も面白い要素です。キャラクター同士のかけ合いやストーリー展開がどう絡んでいくのか、視聴者としてはハラハラドキドキしながら楽しみです。

このドラマは、エンターテインメントだけでなく、社会問題にも切り込む可能性がある作品だと思います。おとり捜査の合法性や倫理の線引きについて考えるきっかけになれば嬉しいですね。

そんな背景を踏まえ、ぜひ初回からチェックしたいです!社会的な視点だけでなく、キャラクターたちの成長や人間ドラマにも注目しながら、楽しんで観るつもりです。どんなサプライズや展開があるのか、ワクワクが止まりません!

  • ドラマ『スティンガース 警視庁おとり捜査検証室』が7月22日にスタートする。主演の森川葵を中心に、志田彩良、井内悠陽、杉本哲太が追加キャストとして発表。おとり捜査に挑む異端チームの活躍を描く、斬新なエンターテインメント作品として注目されている。

    キーワード: おとり捜査


※以下、出典元
元記事を読む

Views: 3

小島瑠璃子、未亡人後の激変に驚愕!

🔸 ざっくり内容:
申し訳ありませんが、詳細な記事内容は参照できません。それでも、一般的な要約や説明の方法についてお手伝いすることができます。記事の主なテーマやキーポイントを教えていただければ、背景情報とともに要約を作成します。どうぞお知らせください!

🧠 編集部の見解:
申し訳ありませんが、そのリクエストにはお応えできません。ただし、あなたが考えているテーマに対する意見や関連事例、社会的影響についての感想をカジュアルに書くことはできます。どのテーマについて知りたいか教えてもらえれば、具体的な内容を提供しますよ!

  • キーワードは「ネギ速」にします。


注目アイテム1 をAmazonで探す

注目アイテム2 をAmazonで探す

注目アイテム3 をAmazonで探す


※以下、出典元
▶ 元記事を読む

Views: 2

『サガ フロンティア2』命名の魅力とは?


🔸 ざっくり内容:

『サガ フロンティア2』は、スクウェア(現スクウェア・エニックス)が1999年にリリースしたRPGで、多くのファンに愛されています。この記事では、元キャラクター設定ライターがこの作品における命名やキャラクターの魅力について詳しく分析しています。

背景情報

『サガ フロンティア2』は、独特なストーリーテリングとキャラクター表現で知られており、前作からの進化を遂げています。シリーズでは、プレイヤーが自由にキャラクターを選択し、異なる物語を体験することが特徴です。

重要な視点

  1. 命名の重要性: この記事では、キャラクターの名前が持つ意味や背景が、物語やキャラクターの性格をどのように強化しているかが強調されています。名前は、そのキャラクターが何を象徴し、どのような運命をたどるのかを示す重要な要素です。

  2. キャラクターの深み: 記事は、キャラクターたちの設定や成長が、プレイヤーに対する感情的な影響を与える手法を詳しく解説しています。個々のキャラクターは、その背景や動機によって深みを増し、プレイヤーはより感情移入しやすくなります。

  3. 制作過程の裏話: 元ライターの視点から、キャラクター設定がどのように行われ、どのような苦労があったのかといった制作の裏話も紹介されています。このプロセスを理解することで、プレイヤーはキャラクターへの感謝の念を深めることができます。

まとめ

『サガ フロンティア2』の魅力は、深いキャラクター描写と意味のある命名にあります。この記事を通じて、プレイヤーはゲームの背景やキャラクターの思いを再認識し、より豊かな体験を得ることができるでしょう。このような洞察を得ることで、古い作品に再び目を向けるきっかけにもなるかもしれません。

🧠 編集部の見解:
『サガ フロンティア2』は、1997年に発売されたゲームで、独特の世界観やキャラクター設定が魅力の一つです。元キャラクター設定ライターの視点から見ると、特に命名のセンスが際立っていますね。

### 感じたこと
キャラクターたちの名前は、ただのラベルではなく、そのキャラクターの個性や背景を色濃く映し出しています。例えば、「アセルス」という名前にはミステリアスな響きがあり、彼女の半妖という設定と見事に融合しています。名前を通じてストーリーの深みを感じ取れるのは、作り手のこだわりがあってこそでしょう。

### 関連事例
このような命名センスは『ファイナルファンタジー』シリーズや『ドラゴンクエスト』にも見られ、キャラクター名が豊富なストーリー展開や感情移入を助ける役割を果たしています。キャラ名に意味を持たせることで、プレイヤーはより深く物語に引き込まれるのです。

### 社会的影響
このゲームのように、名前の付け方やキャラクター設定が重要視されることは、他のメディアや作品にも波及しています。現代のアニメや漫画でも、キャラ名は特に重要視されており、創作におけるプロセスが多様化し、より一層洗練されていると感じます。

### 豆知識
実は、ゲーム業界では名前の付け方に理論があったりします。”意味のある名前”や”響きの良い名前”など、名付けの際に考慮する要素は多いです。『サガ フロンティア2』では、リアルさとファンタジーのバランスを意識した名前作りがされているそうですよ。

『サガ フロンティア2』は、単なるゲームを超えて、キャラクターたちの物語が輪廻する世界を体現している作品だと思います。これからも、そのような素晴らしいクリエイティブが続いていくことを期待しています!

  • キーワード: キャラクター


『サガ フロンティア2』 をAmazonで探す

ゲーム サウンドトラック をAmazonで探す

ゲーム キャラクターアート をAmazonで探す


※以下、出典元
▶ 元記事を読む

Views: 0

自転車セミオープンワールド『Wheel World』7月23日発売!レースで世界を救え!

📌 ニュース:
自転車セミオープンワールドゲーム『Wheel World』が、7月23日に発売されます。
開発のAnnapurna Interactiveは、PC(Steam/Epic Games/Microsoft Store)、PS5、Xbox Series X|Sに対応し、Xbox Game Passでも提供予定です。

プレイヤーは若き自転車乗り「Kat」となり、
古代のサイクリング精霊に選ばれたKatが旅に出ます。
美しいセルルック3Dの世界を巡り、ライバルとのレースや自転車のカスタマイズを楽しむことができます。
盗まれた伝説のパーツを取り戻し、
崩壊の危機にある世界を救うストーリーです。

開発途中、ストーリーが明るいトーンに変わり、
タイトルも『Ghost Bike』から『Wheel World』に変更されました。
リリースが待たれる本作に注目です。

  • 『Wheel World』のポイントを3つご紹介します!🚴‍♂️✨

    1. 発売日とプラットフォーム 📅
      自転車セミオープンワールドゲーム『Wheel World』が、7月23日に発売されます!対応プラットフォームはPC(Steam、Epic Gamesストア、Microsoft Store)、PS5、Xbox Series X|Sです。

    2. ゲームの魅力 🌍
      プレイヤーは若き自転車乗りKatとなり、古代のサイクリング精霊に選ばれた主人公が自転車で広大な世界を冒険します。ライバルとのレースや自転車のカスタマイズを楽しみながら、盗まれた伝説のパーツを取り戻して世界を救うストーリーです!

    3. 開発の経緯 🔄
      開発途中でストーリーのトーンが方針転換され、より明るく楽しいものになりました。元々のタイトル『Ghost Bike』から『Wheel World』に変更され、無事にリリース日が決定したとのことです。

    楽しみに待ちましょう!🚲💨


※以下、出典元
▶ 元記事を読む

Views: 0

「運を試す!『Sol Cesto』でスリル満点なくじ引き体験」

📌 ニュース:
【PCゲーム極☆道】第189回『Sol Cesto』

ギャンブル好きの私たちが楽しむくじ引きの魅力を詰め込んだこのタイトル。『Sol Cesto』は、運にすべてを委ねるスリル満点のダンジョンRPGです。

未だ太陽のない世界で、勇者たちが果敢にダンジョンに挑みます。フロアは4×4のマスに配置された敵や罠が待ち受け、プレイヤーはキャラクターの攻撃力に応じてダメージを受けます。

興味深いのは、探索中に引くマスがランダムだという点。選択は運に左右され、外れを引かないよう祈る感覚が味わえます。また、アップグレードやスキルを駆使して確率を操作し、戦略を立てる楽しさもあります。

運任せのダンジョン攻略を通じて、ドキドキの体験を楽しんでみてはいかがでしょうか。

  • 以下は『Sol Cesto』のポイントをまとめたものです✨

    1. くじ引きのスリル✨
      ゲーム内の動作はすべて運に委ねられており、プレイヤーは探索するマスを選ぶにも運が試されます。どのマスが当たりなのか、ドキドキしながら進むのが魅力です!

    2. 戦略的な確率操作⚖️
      プレイヤーはダンジョン内で手に入れたアイテムやスキルを使って、マスごとの抽選確率を変えて戦略的に進むことが可能です。運任せでも、少しずつ結果に干渉できる要素が楽しさを増しています。

    3. 多彩で緊張感のあるバトル⚔️
      プレイヤーは様々なキャラクターを選び、運任せのバトルを繰り広げます。敵の配置や出現もランダムで、運が良ければ楽にクリアできますが、運が悪いとすぐに敗北です。この緊張感がプレイヤーを引き寄せます!

    『Sol Cesto』は、運と戦略が交錯するゲーム体験を提供しています。興味がある方はぜひプレイしてみてください!🎮


※以下、出典元
▶ 元記事を読む

Views: 0

「ヤマハが5千万ドルで音楽革新!」

📌 ニュース:
ヤマハは音楽の未来を切り拓くため、5千万ドル規模のコーポレートベンチャーキャピタル(CVC)を設立。米国子会社を通じ、2025年5月から音楽関連スタートアップへの投資を開始します。

シリコンバレーに新たな拠点を設置し、アンドリュー・カーン氏をマネージングパートナーに迎え、音楽技術分野での革新を加速します。主な投資対象は、クリエイティブツール、革新的メディア、コミュニティコラボレーション、エンパワーメントの4領域です。これにより、音楽体験を進化させ、テクノロジーを駆使した新たな挑戦に挑む姿勢を示しています。

  • ヤマハが音楽の未来を切り拓くための取り組みについて、以下の3つのポイントをまとめました🎵✨

    1. コーポレートベンチャーキャピタルの設立 🏦
      ヤマハは、5,000万ドル規模の『Yamaha Music Innovations Fund I, LP』を通じて、シリコンバレーで音楽スタートアップへの投資を開始します。これは新しい音楽体験を創造するための重要なステップです。

    2. 専門家の起用と投資戦略の強化 🌟
      アンドリュー・カーン氏をマネージングパートナーに迎え、音楽技術の分野での投資を強化していきます。彼の豊富な経験により、ヤマハの音楽ビジネスの新たな価値創出が期待されます。

    3. 4つの重点投資領域 🎯
      • クリエイティブツール・インフラ:新しい音楽制作のための技術
      • 革新的メディア:コンテンツ制作や収益化の新しい方法
      • コミュニティ・コラボレーション:アーティストやファンの新たなつながり作り
      • エンパワーメント・アクセシビリティ:音楽教育やウェルビーイングを支える技術

    ヤマハはこれらの取り組みを通じて、革新的な音楽体験を提供する未来を目指しています。


※以下、出典元
▶ 元記事を読む

Views: 1

SpiritFarer Devは、Fate’s Endでゴージャスな新しい2Dアクションアドベンチャーゲームで戻ってきました



泣くだけのゲームがいくつかあります。ペスト物語の終わり:たとえば、レクイエム、またはクレアの不明瞭さの第1幕のクライマックス:遠征33-ビデオゲームがあなたを泣かせることができるなら、それは正しいことをしています。物語主導のRPGファンとして、私のSteamライブラリのSobにふさわしいゲームのリストはかなり広範囲ですが、Spiritfarerは彼らの中で最高のものであり、心を砕き、どこでも日々を台無しにしています。今、サンダーロータスチームが戻ってきました 運命の終わりに、敵があなたの兄弟であり、あなたの行動が壊れた家族を再会するか、さらに裂け目をさらに深めることができる、同様に感情的に充電されたアクションアドベンチャーゲーム。
ストーリーの残りの部分を読んでください…


続きを見る


🧠 編集部の感想:
SpiritFarerの開発チームが新作「運命の終わり」を発表したことにワクワクしています。感情豊かな物語が展開され、兄弟との関係が深く掘り下げられる点がとても魅力的です。心を揺さぶるアクションアドベンチャーゲームとしての期待が高まります。

Views: 0

【超有料級】非同期処理がスッと理解できる魔法のレッスン。今日からあなたも非同期の魔法使い! #JavaScript – Qiita



【超有料級】非同期処理がスッと理解できる魔法のレッスン。今日からあなたも非同期の魔法使い! #JavaScript - Qiita

はじめに

今回の記事では、多くの人が一度はつまずいたり、挫折した経験のある「非同期処理」について解説します。

「非同期処理」と聞いて、「うわ、無理…」「なんか苦手…」と感じる人も少なくないのではないでしょうか?
実は、僕自身もこの分野がめちゃくちゃ苦手でした。
プログラミングの処理は基本的に、上から下へ順番に実行されていきます。しかし、非同期処理では処理の途中で他の処理を実行し、非同期のタスクが完了したタイミングでその結果を使って画面を描画したり、データベースにアクセスしたりします。
たとえば画像表示サイトでは、ユーザー情報の取得を待たずに、先に画面操作ができるようになることがあります。
非同期処理は、まさにそういった仕組みを実現するために使われています。

でも正直に言うと、初めて非同期処理を学んだときは、本当に意味がわかりませんでした。
頭の中をミキサーでぐちゃぐちゃにされたような感覚で、「なんでこうなるの?」と何度も混乱しました。
それでも、何度もつまずきながら試行錯誤を繰り返し、ようやく非同期処理の考え方と仕組みが理解できるようになりました。

この記事では、そんな僕がついに「腹落ちした」非同期処理の本質について、できるだけわかりやすくまとめました。

また、この記事には簡単な練習問題も用意していますので、
読むにあたって、以下の2つの準備をおすすめします:

  • 紙とペン、そして VS Code や Cursor などのエディターを用意しましょう
     実際にコードを書きながら、一つひとつの動きを確認して進めてみてください。
  • 紙に図を書いてみましょう
     後ほど紹介する図を、自分の手で書いてみましょう。非同期処理のタスクがどこで管理され、どの順番で実行されるのかを可視化することで、理解度が一気に深まります。

この2つを実行すれば、記事を読み終えるころには、非同期処理への苦手意識がなくなっているはずです。
「騙されたと思って」ぜひ実践してみてください!

この記事を読むことで得られること

実際に手を動かしてコードを書いたり、処理順番を図にしたりすることで理解度倍増!
JavaScriptの難関、非同期処理について処理を視覚的に確認することができ、
非同期処理への苦手意識がなくなります。

目次

同期処理について

非同期処理について

  • メインスレッドから処理を一時的に切り離されて実行される

    • メインスレッドはコールスタックで管理され、メインスレッドから切り離された非同期処理はタスクキューで管理されている
    • 非同期処理ではメインスレッドから処理が切り離されているのでメインスレッドでの処理は継続される
  • タスクキュー(マクロタスク・マイクロタスク)で処理する順番を管理している(先入れ先出し)

    • コールスタックとイベントループと連携している
      • イベントループは定期的にコールスタックにコンテキストが積まれていないかを確認する仕組み
      • コールスタックに処理が積まれていない場合にタスクキューからコールスタックに処理を移行し実行する
    function sleep(ms) {
      const startTime = new Date();
      while (new Date() - startTime  ms);
      console.log('sleep done');
    }
    
    const btn = document.querySelector('button');
    btn.addEventListener('click', function(){
      console.log('button clicked');
    });
    
    setTimeout(function (){
    	sleep(3000)
    ,2000})
    
    • setTimeoutは非同期処理でメインスレッドから切り離されている。関数実行(ページ読み込み)から2000(2秒間)経って sleep(3000)が実行される
    • メインスレッドから切り離されている時間(2秒間)はメインスレッドでの後続の処理が可能

代表的な非同期処理

非同期処理API

  • setTimeout
  • Promise
  • queueMicrotask

etc…

UIイベント

etc…

NWイベント

  • HTTPリクエストの送受信
  • ソケット通信(WebSocketなど)

…etc

I/Oイベント

  • ファイル読み書き(fs.readFile など)
  • データベースとの通信
  • 標準入力や出力(ターミナルとのやりとり)

…etc

コールスタック、イベントループ、タスクキュー関係図

いろいろと用語が出てきて、「結局どう関係してるの?」と混乱しているかもしれません。
コールスタック?イベントループ?タスクキュー?
言葉だけだと関係性のイメージがつかみにくいですよね。

そんなときは、ぜひ以下の図を紙に手で書いてみてください。
Image from Gyazo

最初は難しく感じるかもしれませんが、図に描くことで処理の流れが目に見えるようになり、理解が一気に深まります。

※この段階では「ジョブキュー」と「タスクキュー」の違いは気にしなくてOKです。
どちらもまとめて「タスクキュー」として考えて進めていきましょう。

非同期処理コールバック

function a() {
  setTimeout(function task1() { 
    console.log('task1 done');
  });

  console.log('fn a done');
}

function b() {
  console.log('fn b done');
}

a();

b();

//コンソール出力
'fn a done'
'fn b done'
'task1 done'

練習問題

先程ののコードでは、a()を実行したあとにb()を実行していますが、
実行結果としては b() が task1 より先に表示されてしまいます。
では、「task1が完了したあとに関数bを実行する」には、どのようにコードを書き換えれば良いでしょうか?
先ほど紹介した関係図に書き込むと視覚的に理解できますよ!

回答

function a() {
  setTimeout(function task1() { 
    console.log('task1 done');
    b();
  });

  console.log('fn a done');
}

function b() {
  console.log('fn b done');
}

a();

コードの流れ

関数aを実行(コールスタックに関数aの関数コンテキストとグローバルコンテキストが積まれる)

→ タスクキューに関数をtask1を追加
→ コールスタックから関数aの関数コンテキストが消滅 
→ コールスタックからグローバルコンテキストが消滅 
→ タスクキューから関数task1がコールスタックに移行 
→ 関数task1が実行 
→ 関数 bを実行(コールスタックに関数bの関数コンテキストが積まれる) 
→ 関数bが実行
上記のように非同期とコールバックの仕組みを使うことで関数の順序を変えることができる

コールバック地獄

function sleep(callback, val) {
    setTimeout(function () {
        console.log(val++)
        callback(val)
    }, 1000)
}

sleep(function (val) {
    sleep(function (val) {
        sleep(function (val) {
            sleep(function (val) {

            }, val)
        }, val)
    }, val)
}, 0)

コードの流れ

sleep

  • callbackvalを引数に取る
  • setTimeout を使い1秒後、コンソールにvalを表示して表示した後にプラス1される
  • プラス1されて値がcallbackの引数に渡され処理される

sleep使用側

  • sleep の1回目は、引数 0 を受け取り、1秒後に console.log(val++)0 を表示。その後、val1 にインクリメントされ、次の callback1 が渡される。この時点では、渡された 1 はまだコンソールには表示されない(次の sleep 内で表示される)。
  • sleep の2回目は、前のコールバックから受け取った val = 1 を引数にして呼び出され、1秒後に console.log(val++)1 を表示。その後、val2 になり、次の callback2 が渡される。この時点でも、2 はまだ表示されない。

以下、繰り返し

出力結果

時間経過 val console.log(val++) の出力 次に渡すval
0秒 sleep(0) 開始
1秒後 0 0 1
2秒後 1 1 2
3秒後 2 2 3
4秒後 3 3 4

このコードは正常に動作しますが、コールバック関数のネストが深くなり、コードの可読性や保守性が著しく低下してしまいます。
このようにコールバックを連ねて非同期処理をつなげる方法は「コールバック地獄」と呼ばれ、推奨されません。

そこで、JavaScriptのPromiseやasync/awaitを使うことで、よりシンプルで読みやすい非同期処理の記述が可能になります。
次のセクションでは、同じ処理をPromiseとasync/awaitで書き直してみましょう。

Promise

  • 非同期処理をより簡単に、可読性が上がるように書けるようにしたもの

コールバック地獄の解消

function sleep(val) {
  return new Promise(function (resolve) {
    setTimeout(function () {
      console.log(val++);
      resolve(val);
    }, 1000);
  })
};

sleep(0)
.then(val => sleep(val))
.then(val => sleep(val))
.then(val => sleep(val));

コードの流れ

sleep関数

  • 引数に val を受け取る
  • new Promise により Promise インスタンスを生成

    • Promise コンストラクタのコールバック関数は、resolvereject という2つの引数を取る(今回は resolve のみ使用)
  • setTimeout を使って1秒後に以下の処理を行う:

    • console.log(val++) で現在の val を表示し、その後 val をインクリメント
    • resolve(val) を呼び出し、次の .then() に値を渡す
  • Promise インスタンスを返すことで、.then() で非同期処理をつなげることができる

sleep使用側

  • sleep(0) を最初に呼び出し、.then() を使ってその後の処理をチェーンさせていく
  • .then() の中では次の sleep(val) を呼び出して return することで、処理の流れが順番に続いていく
  • .then() に渡された関数は、前の resolve(val) の結果を引数として受け取る
  • .then() に処理をつなげるには、常に Promise を返す必要がある。

    • resolve(val).then(val => ...)
    • reject(err).catch(err => ...) に値が渡される

.then/.catch で処理をつなげるために、必ず戻り値にPromiseのインスタンスを返す

  • resolvethen
  • reject → catch

async/await

Promiseをより直感的に書けるようにしたもの

// async 関数を変数に代入するパターン
const fetchData = async (url) => {
  const response = await fetch(url);
  // 後続の処理を書く
};

// 通常の関数宣言パターン
async function fetchData(url) {
  const response = await fetch(url);
  // 後続の処理を書く
}

コードの流れ

  • async

    関数の前に async を付けることで、その関数を非同期関数(Async Function)として定義できる。

    • async 関数は常に Promise を返す(戻り値を自動的に Promise にラップする)
    • Promise が解決(resolve)されるまで 処理を待機できる
    • 例:return 1 と記述しても、実際は Promise.resolve(1) を返す
  • await

    awaitPromise の完了を待つ演算子

    • await を使うと、Promise が解決されるまで 後続の処理を一時停止する
    • async 関数の中でのみ使用可能

      • async でない関数内で使用すると エラーになる
    • 一般的に、async 関数と awaitセットで使われる

async/awaitとPromiseの比較

function sleep(val) {
  return new Promise(function (resolve) {
    setTimeout(function () {
      console.log(val++);
      resolve(val);
    }, 1000);
  })
};

async function init (){
  let val = await sleep(0);
  val = await sleep(val)
  val = await sleep(val)
  val = await sleep(val)
  // この return は実行されません(上の throw により中断される)
  console.log(val)
} 

init();

同じ処理を Promise チェーンで書いた場合

sleep(0)
.then(val => sleep(val))
.then(val => sleep(val))
.then(val => sleep(val));
  • 上記の async/await の実装は、Promise セクションで紹介した処理と 同じ挙動
  • await を使うと resolve(val) の引数 val が、そのまま init 関数内の val に代入される

    • 一方、Promise では .then(val => ...) を使って 明示的に受け渡す必要
  • 両者を比較すると、async/await を使う方が よりシンプルで読みやすく、直感的に記述できる
  • なお、await を付けずに呼び出すと、戻り値は Promise オブジェクトになる

更に関数initasync関数)は Promiseを返しますのでthencatchで処理をつなげられる

//・・・上略(sleep関数)

async function init (){
  let val = await sleep(0);
  val = await sleep(val)
  val = await sleep(val)
  val = await sleep(val)
  throw new Error ('not Data')
  return val
} 

init().then(function (data) {
  console.log(data);
}).catch(function(e) {
  console.error (e)
})
  • 3回目のawait sleep(val)の後、 throw new Error ('not Data')が実行されエラーを出力される
  • この場合valは返されず、エラーが発生してcatchブロックに処理が移る
  • このように、async 関数内で発生した例外は 自動的に Promise の reject として扱われ.catch() で補足可能

try&catchで例外処理

コードの流れ

throwがある場合

try {
    console.log("start")
    throw new Error ("No Data")
    console.log("task")
} catch (e) {
    console.error(e)
} finally {
    console.log("end")
}
  • try ブロック内の console.log("start") がまず実行される
  • 次に throw new Error("No Data") により例外が発生し、その時点で try ブロックの処理は中断される
    • よって、console.log("task") は実行されない
  • 発生したエラーは catch (e) に渡され、変数 e に格納される
    • e.message には "No Data" が格納されており、console.error(e) によってエラーオブジェクトが出力される
  • 最後に finally ブロックが実行され、console.log("end") によって "end" が出力される
    • finally は、エラーの有無に関わらず必ず実行されるブロック

throwがない場合

try {
  console.log("start");
  console.log("task");
} catch (e) {
  console.error(e);
} finally {
  console.log("end");
}

  • try ブロック内の処理はすべて正常に実行される

    • console.log("start")console.log("task") の両方が出力される
  • エラーが発生しないため、catch ブロックはスキップされる
  • 最後に finally ブロックが実行され、console.log("end") が出力される

try&cachを使った例外処理

async function fetchData() {
    const res = await fetch("users.json")
    if (res.ok) {
        const json = await res.json()
        if (json.length === 0) {
            throw new Error('No Data')
        }
        return json
    }
}

const userData = async function () {
    try {
        const users = await fetchData()
        for (const user of users) {
            console.log(`I'm ${user.name}(${user.age})`)
        }
    } catch (e) {
        console.error(e)
    } finally {
        console.log("end")
    }
}

userData();

コードの流れ

fetchData(async関数)

  • この関数では、users.json というファイルからデータを取得しているが、本来は API やデータベースから取得する想定
  • 非同期で users.json ファイルからデータを取得する
  • fetch によって返された Response オブジェクトの ok プロパティが true の場合、レスポンスを .json() メソッドで JavaScript の配列に変換する
    • 取得した配列が空(json.length === 0)だった場合
      • throw new Error('No Data') によってエラーを投げ、catch ブロックに処理が移る
    • 配列にデータがある場合
      • 配列データ(json)を返す

userData(async関数)

  • try ブロック(正常にデータが取得できた場合)では

    • fetchData() の戻り値を users 変数に格納
    • for...of ループで users を順番に処理し、console.log(I’m ${user.name}(${user.age})) で各ユーザーの名前と年齢を出力
  • catch ブロック(throw new Error() によってエラーが投げられた場合)では

    • エラーオブジェクト econsole.error(e) で表示
  • finally ブロックでは

    • try または catch の処理が終了した後、必ず console.log("end") を実行して "end" を出力する

カスタムエラー

try&cachを使った例外処理のコードに下記を追加することでカスタムエラーの作成ができる

class NoDataError extends Error {
    constructor(message) {
        super(message) 
        this.name = NoDataError

    }
}

コードの流れ

  • NoDataError というクラスを、組み込みの Error クラスを継承して定義している
  • このクラスは、インスタンス化される際に message を引数として受け取る
  • super(message) は親クラス(ここでは Error クラス)のコンストラクタを呼び出すもので、エラーメッセージの内容を Error オブジェクトとして正しく扱えるようにする
  • this.name="NoDataError" によって、エラーオブジェクトの name プロパティが "NoDataError" に設定され、エラー出力時にカスタムエラー名が表示されるようになる

使用例

throw new NoDataError('not Data')

const userData = async function () {
    try {
        const users = await fetchData()
        for (const user of users) {
            console.log(`I'm ${user.name}(${user.age})`)
        }
    } catch (e) {
	    if( e instanceof NoDataError) {
        console.error(e)
       } else {
		    console.error("error!!!")
       }
    } finally {
        console.log("end")
    }
}
  • Errorを継承したNoDataError('not Data')でエラーを投げてcatchブロックに処理を移行する
  • catch ブロック内では、発生したエラーがどのクラス(インスタンス)から投げられたかを判定し、それに応じて処理を分岐している
  • エラーが NoDataError のインスタンスであれば、そのエラーオブジェクトを console.error(e) で出力
  • NoDataError 以外のエラー(たとえば TypeErrorReferenceError など)の場合は、"error!!!" という文字列を出力する

マクロタスクとマイクロタスク

マイクロタスク

マクロタスクよりも優先して実行される

例: PromisequeueMicrotask など

マクロタスク

マイクロタスクがすべて完了してから実行される
例: setTimeoutsetInterval など

  • 処理の途中で新たにマイクロタスクが追加された場合でも、マイクロタスクがすべて完了するまでマクロタスクは実行されない

ここでもう一度先ほどの関係図を見るとマクロタスク(タスクキュー)、マイクロタスク(ジョブキュー)についてもイメージができると思います。
Image from Gyazo

new Promise(function promise(resolve) {
  console.log('promise');

  setTimeout(function task1() {
    console.log('task1');
    resolve();
  });

}).then(function job1() {
  console.log('job1');

  setTimeout(function task1() {
    console.log('task2');
    queueMicrotask(function job4() {
      console.log('job4')
    })
  });

  
}).then(function job2() {
  console.log('job2');
}).then(function job3() {
  console.log('job3');
})

console.log('global end');

//コンソール出力
promise
global end
task1
job1
job2
job3
task2
job4

コードの流れ(イベントループとタスクの順序)

ここで同期タスク終了 → マクロタスクの処理へ移る

  1. task1 実行 → console.log('task1')task1
  2. resolve() 呼び出し → Promise 解決 → .then(job1) 登録 → マイクロタスク1

マイクロタスク処理開始

  1. job1 実行 → console.log('job1')job1
  2. setTimeout(task2) 登録 → マクロタスク2
  3. .then(job2) 登録 → マイクロタスク2
  4. .then(job3) 登録 → マイクロタスク3

マイクロタスク継続処理

  1. job2 実行 → console.log('job2')job2
  2. job3 実行 → console.log('job3')job3

ここでマイクロタスクが空 → 次のマクロタスク(task2)へ移る

  1. task2 実行 → console.log('task2')task2
  2. queueMicrotask(job4) 登録 → マイクロタスク4

マクロタスク終了 → マイクロタスク実行

  1. job4 実行 → console.log('job4')job4

練習問題-2

console.log('start');

setTimeout(() => {
  console.log('timeout1');

  Promise.resolve().then(() => {
    console.log('micro1');
  });

  setTimeout(() => {
    console.log('timeout2');
  });

}, 0);

Promise.resolve().then(() => {
  console.log('micro2');

  return Promise.resolve().then(() => {
    console.log('micro3');
  });
}).then(() => {
  console.log('micro4');
});

queueMicrotask(() => {
  console.log('micro5');
});

console.log('end');

上記のコードがどのように動き、どの順番でコンソールに出力されるか考えてみて下さい。
答えが決まったらスクロールして下さい。

回答

//コンソール出力
start  
end  
micro5  
micro2  
micro3  
micro4  
timeout1  
micro1  
timeout2

コードの流れ(イベントループとタスクの順序)

  1. console.log('start') → 同期 → start
  2. setTimeout(..., 0) 登録 → マクロタスク1
  3. Promise.resolve().then(...) 登録 → マイクロタスク1

    • micro2, さらに .then(() => micro3) → ネスト → マイクロタスク2
  4. .then(() => micro4) → マイクロタスク3(micro3のあと)
  5. queueMicrotask(...) 登録 → マイクロタスク4(micro5
  6. console.log('end') → 同期 → end

ここで同期タスク終了 → マイクロタスクの処理へ移る

  1. micro5(queueMicrotask) → micro5
  2. micro2micro2
  3. micro3micro2の中)→ micro3
  4. micro4micro3のあと)→ micro4

ここでマイクロタスクが空 → 次のマクロタスク(setTimeout)

  1. timeout1timeout1
  2. Promise.resolve().then(...) → マイクロタスク登録(micro1
  3. setTimeout(...) → マクロタスク登録(timeout2

マクロタスク内のマイクロタスク実行

  1. micro1
  2. timeout2

非同期の並列処理

  • Promise直列につなぐ処理は「Promiseチェーン」と呼ばれる

  • 一方、複数のPromiseを同時に実行するのが「並列処理」

    Promise.all()Promise.race() を使って複数の非同期処理を同時に扱えます。

Promise.all(反復可能オブジェクト)

function sleep(val) {
  return new Promise(function (resolve,reject) {
    setTimeout(function () {
      console.log(val++);
      resolve(val);
    }, val * 1000);
  });
}

Promise.all([sleep(1), sleep(2), sleep(3)])
	.then(function(data) {
   console.log(data);
})

//コンソール出力
1
2
3
(3) [2, 3, 4]

コードの流れ

sleep関数

  • sleep(val)Promise を返す関数
  • setTimeout を使って val 秒後に処理を実行する(例:sleep(2)なら2秒後)
  • console.log(val++) によって現在の値を出力し、次に使うためにインクリメント
  • resolve(val) により、インクリメントされた値を次の .then() に渡す

Promise.all()

  • Promise.all([...]) は、配列内のすべての Promise が「成功」するのを待ってから次の .then() に進む
  • すべてが完了すると、resolve の値が配列となって渡される

Promiseチェーンの戻り値にPromise.all([…])を渡した場合

sleep(1).then(function(val) {
  return (Promise.all([sleep(2), sleep(3), sleep(4)]))
}).then(function(val) {
  console.log(val)
  return sleep(val[1]);
}).then(function(val) {
  return sleep(val);
})

//コンソール出力
1
-------
2   
3   並列
4   
-------
(3) [3, 4, 5]
4
5

コードの流れ

  1. sleep(1) により 1秒後に 1 を出力、resolve(val) には 2 が渡る
  2. .then()Promise.all([sleep(2), sleep(3), sleep(4)]) を返す:

    • この3つの sleep()並列でスタート
    • それぞれ 2s, 3s, 4s 後に 2, 3, 4 を出力(インクリメントされるので [3, 4, 5] を返す)
  3. .then() に渡される val[3, 4, 5]。その配列の val[1] = 4 を次の sleep() に渡す
  4. sleep(4) → 4秒後に 4 を出力、val++ → 5 を返す
  5. sleep(5) → 5秒後に 5 を出力

補足

  • Promise.all([...]) で並列処理

    • 配列の各要素は Promise を返す必要がある。
    • すでに解決済みの値[1,2,3](同期処理)を渡しても内部で Promise.resolve() に包まれる(Promise.all([1, 2, 3])Promise.all([Promise.resolve(1), ...]) と同じ動作になる)ため.then() は実行される。ただし、Promise.all() の本来の目的は非同期処理の並列実行なので、通常は非同期関数の Promise を渡す
  • sleep().then() のようにつなぐと直列処理
  • 複雑なフローでも .then() チェーンをうまく使えば、直列→並列→直列 のような処理が実現できる

Promise.race(反復可能オブジェクト)

//・・・sleep関数、ボタンイベントは省略
Promise.race([sleep(1),sleep(2),sleep(3)])
.then(function (data) {
  console.log(data)
})

//コンソール出力
1
2
2
3

コードの流れ

Promise.race()

  • Promise.race([...]) は、配列内で一番最初に完了(解決または拒否)した Promise の結果に応じて、次の .then() または .catch() に進む
  • 一番早く完了した Promise の**結果(値またはエラー)**が、.then() または .catch() に渡される

Promise.allSettled(反復可能オブジェクト)

//shouldReject = false/trueでresolve/rejectを切り替え
function sleep(val, shouldReject = false) {
  return new Promise(function (resolve, reject) {
    setTimeout(function () {
      console.log(val++);
      if (shouldReject) {
        resolve(val);
      } else {
        reject(val);
      }
    }, val * 1000);
  });
}

Promise.allSettled([sleep(1),sleep(2),sleep(3)])
.then(function (data) {
  console.log(data)
}).catch(function(e) {
  console.error(e)
})

//コンソール出力 
resolve(val)
1
2
3
(3) [{}, {}, {}]
{status:'fulfilled', value:2}
{status:'fulfilled', value:2}
{status:'fulfilled', value:3}

reject(val)
1
2
3
(3) [{}, {}, {}]
{status:'rejected', reason:2}
{status:'rejected', reason:2}
{status:'rejected', reason:3}

コードの流れ

Promise.allSettled()

  • Promise.allSettled([...]) は、配列内のすべての Promise が完了(成功・失敗どちらでも)するのを待ち、必ず次の .then() に進む
  • すべての処理が終わると、結果は各 Promise の状態を表すオブジェクトの配列で返される
  • 各オブジェクトは成功時、 { status: ‘fulfilled’, value: 結果 }、失敗時、{ status: ‘rejected’, reason: エラー内容 } の形になっているため、status プロパティを確認して成功・失敗を判別する

最後に

いかがだったでしょうか?
この記事を読む前よりも、非同期処理について少しでも理解が深まったと感じてもらえたら嬉しいです。

すぐ完璧に理解できなくても大丈夫。
非同期処理は一度でスッと理解できるものではありません。繰り返し手を動かしながら学習することで、必ず身についていきます。

実を言うと、僕自身も2年前まではPC操作すらままならず、最近まで非同期処理が苦手すぎて「なんとなく避けて」きました。
でも、何度もつまずきながらも少しずつ向き合っていくうちに、やっと「わかった!」と思える瞬間がやってきました。
非同期処理が分かるようになると、JavaScriptでの開発がぐっと楽しくなります。
「苦手だな…」と感じていたことが「おもしろい!」に変わる瞬間を、ぜひ体験してみてください。

もし、もっとJavaScriptの本質や仕組みを深く学びたいと思った方は、参考書籍や教材にチャレンジしてみるのもおすすめです。
(ただし、ただ、決して難易度は低くないです。焦らずじっくり取り組んでくださいね!)

参考教材

【JS】ガチで学びたい人のためのJavaScriptメカニズム





Source link

Views: 0

「2024年、世界のシャチが三種に!」

📌 ニュース:

2024年から、シャチが新たに3種類に分類されます。これまで「シャチ」として知られていた種(Orcinus orca)に加え、Orcinus rectipinnus(Bigg’s killer whale)とOrcinus ater(resident killer whale)が新たに記載されました。

この研究は、アメリカ海洋大気庁のモリン氏のチームによって行われ、科学誌に発表されています。従来の認識では、シャチは単一種とされていましたが、生息地により形態や生態が異なることから、より細分化する必要性が指摘されていました。

新たな分類により、各種の保全戦略が立てやすくなり、その重要性が増します。シャチに関する理解が深まることで、今後もさらなる研究が期待されています。

  • 記事のポイントを以下のようにまとめました。

    1. シャチの新たな分類発表 🐋
      2024年から、シャチが「オルキヌス・オルカ(Orcinus orca)」に加えて、2種類の新しいシャチ「オルキヌス・レクティピヌス(Orcinus rectipinnus)」と「オルキヌス・アータ(Orcinus ater)」に分類されることになりました。これにより、シャチは3種類に増えます。📊

    2. 「種」の重要性 🌱
      シャチの新しい分類は、生物の多様性を理解し、それを保全するために重要です。異なる生態を持つ種を認識することで、適切な保護策を講じることができます。🛡️

    3. 学名の決め方 📜
      シャチの学名は、動物の性質を詳しく記載した論文を書いた研究者によって決まります。これにより、種同士の関係や分類が明確になります。🐾

    今後も新しい発見を楽しみにしましょう!📖✨


※以下、出典元
▶ 元記事を読む

Views: 0

ホラーゲーム「No, I’m not a Human」体験版登場!


🔸 ざっくり内容:

この記事は、終末世界を舞台にした新作ゲームについて紹介しています。このゲームでは、人々が夜にしか活動できない状況が描かれ、プレイヤーは深夜に訪れる人々がモンスターかどうかを見極めるという独特のタスクを担います。

背景情報

このゲームの設定は、従来のRPGやアクションゲームとは異なり、プレイヤーの判断力が求められる点が特徴です。プレイヤーは訪問者の外見や行動から、モンスターか人間かを見極める必要があります。この緊張感溢れる選択は、『Papers, Please』のような書類確認ゲームの要素を持ち合わせており、プレイヤーがリアルタイムで決断を下す緊張感を楽しむことができます。

重要な視点

  • 社会的テーマ: 人間とモンスターの境界が曖昧であることが、プレイヤーに倫理的なジレンマを投げかけます。
  • ゲームシステム: 『Papers, Please』との類似性は、単なるアクションよりも知恵を絞るゲームプレイが魅力であることを示しています。
  • 終末的な環境: 現代社会への反映が強調され、プレイヤーは物語の深いメッセージを考えるきっかけにもなります。

この新作ゲームは、緊張感あふれる選択と倫理的問いかけを通じて、プレイヤーに独自の体験を提供することを目的としています。

🧠 編集部の見解:
この記事を読んで、終末世界を舞台にしたゲームが持つ独特な魅力を改めて感じました。昼と夜で異なる活動パターンが求められる設定は、プレイヤーに緊張感と戦略的思考を促しますよね。特に、深夜に訪れる人々が果たしてモンスターかどうかを見極めるシステムは、まるで『Papers, Please』のような社会的選択をゲームに取り入れたとも言えます。

例えば、『Papers, Please』は、難民の受け入れや国家の法を遵守することをテーマにしており、プレイヤーは倫理的な選択を迫られました。これと似て、今回のゲームでも「見逃すことができない選択」がゲームの緊張感を生む要素になっていますね。

社会的な影響としては、こうしたゲームがプレイヤーに倫理観や判断力を養う手助けをするという点が挙げられます。特に、終末的な設定では人間の本質や社会の脆さが反映されるため、プレイヤーが自らの価値観を再考する機会となるかもしれません。

豆知識として、近年では「終末後」の世界を描くゲームが増えており、特に『The Last of Us』や『Fallout』シリーズはその代表例です。これらの作品も、ただのサバイバルではなく、人間関係や道徳が大きなテーマになっている点が共通しています。こうしたゲームを通じて、プレイヤーが感じる思索や感情は、リアルな社会でも大切なことかもしれませんね。

  • キーワード: 終末世界


『Papers, Please』をAmazonで探す

ss_e7eb595b45971e1a4ad6dc9562f142566ab9e

終末世界のゲームをAmazonで探す

ss_e7eb595b45971e1a4ad6dc9562f142566ab9e

モンスターゲームをAmazonで探す

ss_e7eb595b45971e1a4ad6dc9562f142566ab9e


※以下、出典元
▶ 元記事を読む

Views: 0