0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

JavaScript入門 その7:非同期処理、モジュール

Last updated at Posted at 2023-11-14

JavaScript入門の書籍を読んで書いてあったこと+自分で調べたことのメモ書きその7。非同期処理、モジュール(export、import)。

非同期処理

fetchとPromiseオブジェクト

fetch

fetch(resource[, options]) はネットワークから指定したリソースを取得する関数である。
引数はURL、Requestオブジェクト。
options でリクエストメソッドの指定などができる。
リソースが取得できたらPromiseオブジェクトを返す。

Promise.protype.then

Promise のメソッド then(onFulfilled[, onRejected]) は最大2つの引数を取る。1番目の引数は処理が成功した(Promiseが履行された場合)のコールバック関数、2番目の引数は処理が失敗した場合(Promiseが拒否された)場合のコールバック関数である。
戻り値はPromiseで、then()メソッドのチェーンにより連続した非同期処理を記述することができる。

let result = document.querySelector("#result");
let url = "/test.json";
fetch(url)
  .then((response) => {
    if (!response.ok) {
      throw new Error("failed.");
    }
    return response.json();
  })
  .then((data) => {
    result.innerText = data.text;
  });

前のthen の引数である無名関数の戻り値が次のthenの引数になる。
4行目のthenの引数 response はReponseオブジェクト、10行目のthenの引数dataはJSONのオブジェクトである。
response.json() の戻り値はPromiseオブジェクトである。
fetch が成功したかのチェックは5行目のように response.ok で行う。404の場合はPromiseは履行されるので。

async/await

async/awaitを使うことによってfetchとPromiseのthenを使った記述よりもさらに通常の処理に近い形で非同期処理を記述できる。
async/awaitでは非同期処理を行いたい処理を非同期化数の中にまとめて書く。関数定義の前にasyncを付けると非同期関数となる。非同期関数内の処理でawaitのところでPromiseが決定(履行または拒否される)まで一時停止する。
先のfetchとPromiseのthenを使った例をasync/awaitを使って書き換えると下記になる。3行目にawaitいるかな?とも思ってしまうがreponse.json()(Responseのインスタンスメソッド)の戻り値はPromiseオブジェクトなので必要なのだろう。ようはPromiseオブジェクトを返すところにawaitがいると考えればいいのではないかと思う。たぶん。

async function getTestJSON(url) {
  let response = await fetch(url);
  let data = await response.json();
  let result = document.getElementById("result");
  result.innerText = data.text;
}

getTestJSON("/test.json");

モジュール

HTMLにscriptタグを複数書けば複数のJavaScriptファイルを読み込むことができる。しかしその場合は同名の変数、関数があると名前が衝突する。
この問題はモジュールで解決できる。モジュールはスコープが独立しておりモジュール間では関数などの定義の段階では名前の衝突が起こらない。

モジュールの使用にはimportとexportを利用する。HTMLではscriptタグのtype属性をmoduleとする

※importとexportでモジュールを使う方式は ES Modules。これとは別に CommonJS というモジュールを使う仕組みがある。よく名前を聞く node.js は CommonJS を使っている。

export

export { 名前1 [as 別名1, 名前2... }
波括弧の中にカンマ区切りでエクスポートするモジュールの定数名、関数名、クラス名を書く。asで別名を付けてエクスポートすることもできる。

下記のように宣言と同時にエクスポートすることもできる。

export const c1 = "abc";

export function someFunc() {
  console.log("someFunc");
}

デフォルトエクスポートというものがあるが、そちらはとりあえず詳細は触れずにおく(正直よくわからない)。

import

import { 名前1 [as 別名1, 名前2... } from モジュールのファイルのパス
import * from モジュールのファイルのパス
波括弧の中にカンマ区切りでインポートする定数名、関数名、クラス名を書く。asで別名を付けてインポートすることもできる。波括弧の部分を*にすると指定したモジュールでエクスポートされているものすべてをインポートする。

import * from as モジュールオブジェクト名 from モジュールのファイルのパス
as でモジュールオブジェクトを作成すると、エクスポートしたものを モジュールオブジェクト名.エクスポートしたものの名前 で利用できる。

例:
module_a.js:testFuncmaskObjectをエクスポートしている。maskObjectにはsomeObjectという別名を付けている。

const testFunc = () => {
  console.log("module_a testFunc!");
};

const maskObject = {
  show() {
    console.log("module_a maskObject!");
  },
};

const innerFunc = () => {
  console.log("innerFunc!");
}

export { testFunc, maskObject as someObject };

console.log("module_a export side");

module_b.js:testFuncをエクスポートしている。modulea.js でエクスポートした関数と同じ名前。

const testFunc = () => {
  console.log("module_b testFunc!");
};

export { testFunc };

console.log("module_b export side");

import.js:module_a.js, module_b.jsでエクスポートされた関数、オブジェクトをインポートしたして利用している。module_b.js からモジュールオブジェクトmoduleBを作成して利用している。

import { testFunc, someObject } from "/js/modules/module_a.js";
import * as moduleB from "/js/modules/module_b.js";

testFunc();
someObject.show();

moduleB.testFunc();

console.log("import side");

HTMLファイル:scriptタグで type="module" としている。

<script src="/js/import.js" type="module"></script>

実行結果(consoleへの出力)

module_a export side
module_b export side
module_a testFunc!
module_a maskObject!
module_b testFunc!
import side

参考情報

書籍

解きながら学ぶJavaScriptつみあげトレーニングブック | マイナビブックス 9章

WEBページ

フェッチ API の使用 - Web API | MDN
Promise - JavaScript | MDN
Response.json() - Web API | MDN
JavaScript モジュール - JavaScript | MDN
CommonJSとES Modulesについてまとめる

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?