ホームページ >ウェブフロントエンド >jsチュートリアル >イベントループを使用した mjs と cjs

イベントループを使用した mjs と cjs

WBOY
WBOYオリジナル
2024-09-04 16:39:321059ブラウズ

導入

開発者の皆さん、こんにちは!

今日は、Node.js の .mjs (ECMAScript モジュール) と .cjs (CommonJS モジュール) の違いについて説明します。 React、Next.js、Vue などの最新のフレームワークはモジュールのサポートを自動的に処理することがよくありますが、Node.js を直接操作する場合、特にイベント ループと実行順序に関してこれらの違いを理解することが重要です。

この議論の主な目標はイベント ループに向けてであり、次のセクションではいくつかのケースを見ていきます。

基本情報

mjs (ECMAScript モジュール) は、

import fs from 'fs'
import https from 'https'

cjs (CommonJS モジュール) のサポート

const fs = require('fs')
const https = require('https')

イベントループと実行順序

Node.js イベント ループは、特定の役割と優先順位を持つさまざまなキューを処理します。実行順序に影響を与える 2 つの重要な関数は process.nextTick() と setImmediate() であり、これらを時々使用します。

process.nextTick と setImmediate

process.nextTick と setImmediate の違いを知っていれば、それは素晴らしいことですが、そうでなくても、非常に基本的な考え方です

process.nextTick は、コードの一部が現在の関数の後、非同期 I/O 操作の前に実行されるようにします。

setImmediate は、I/O イベントの後、イベント ループの次の反復で実行されるコールバック関数をスケジュールします。

現在のコード -> process.nextTick ->あらゆる I/O 操作 -> setImmediate

コード例

実行順序を示すコード スニペットを調べてみましょう:

//In case of mjs
import https from "https";
import fs from "fs";

//In case of cjs
const https = require("https");
const fs = require("fs");

setImmediate(() => {
    console.log("setImmediate callback");
});

process.nextTick(() => {
    console.log("nextTick callback");
});

fs.readFile("./async.cjs", (err, data) => {
    console.log("file IO Callback");
});

fs.readdir(process.cwd(), () => console.log("file IO Callback 2"));

https.get("https://www.google.com", (res) => {
    console.log("https callback");
});

setImmediate(() => {
    console.log("setImmediate callback 2");
});

Promise.resolve().then(() => {
    console.log("Promise Callback");
});

process.nextTick(() => {
    console.log("Process nextTick console");
    process.nextTick(() => {
        console.log("Process nextTick console 2");
        process.nextTick(() => {
            console.log("Process nextTick console 3");
            process.nextTick(() => {
                console.log("Process nextTick console 4");
            });
        });
    });
});

Promise.resolve().then(() => {
    console.log("Promise Callback 2");
});

console.log("Main thread mjs");

Promise.resolve().then(() => {
    console.log("Promise Callback 3");
});

予想される実行順序と実際の実行順序

コードはこのように実行され、実行されるはずです

  • メインスレッド
  • コールバックを約束する
  • nextTick コールバック
  • setImmediate コールバック
  • I/O コールバックと出力は次のようにする必要があります。
Main thread mjs
Promise Callback
Promise Callback 2
Promise Callback 3
nextTick callback
Process nextTick console
Process nextTick console 2
Process nextTick console 3
Process nextTick console 4
setImmediate callback
setImmediate callback 2
file IO Callback
file IO Callback 2
https callback

でも、mjs の場合もそうなのでしょうか?
そうではありません!

これは mjs と cjs の出力です

mjs vs cjs with Event Loop

process.nextTick や setImmediate と同様に、Promise でも同じ動作が見られます。

理由は何ですか?

どうやら、setImmediate と process.nextTick に関して mjs (ECMAScript モジュール) と cjs (CommonJS モジュール) ファイルの間で観察されている動作の違いは、Node.js が異なるモジュール システムでイベント ループとマイクロタスクを処理する方法に起因しているようです。 .

ESM (.mjs) の場合:

  • ESM では、Node.js は別のアプローチを使用してメイン モジュールの実行を処理します。
  • メイン モジュールのコードは非同期関数でラップされ、その後実行されます。
  • これにより、すべてのマイクロタスク (process.nextTick と Promises を含む) が処理された後、イベント ループの次の反復で setImmediate コールバックがスケジュールされます。

CommonJS (.cjs) の場合:

  • CommonJS では、メイン モジュールのコードは同期的に実行されます。
  • これは、setImmediate コールバックがすぐにスケジュールされ、十分に早くキューに入れられていれば、いくつかのマイクロタスクの前に実行できることを意味します。

フレームワークの動作

Express および Nextjs アプリ (開発モード) でこの動作をテストしました。興味深いことに、Express は cjs のように動作し、Nextjs は mjs のように動作しました。最初のログセットは Express からのもので、次は Nextjs

からのものです。

mjs vs cjs with Event Loop

結論

Node.js を直接操作する場合、.mjs ファイルと .cjs ファイルの実行順序の違いを理解することが重要です。これが、ファイルに対するこれらの関数の違いと実行をもう少しよく理解するのに役立つことを願っています。したがって、次回アプリでこれらの機能をプレイしたり試したりするときは、次の点に留意してください :)

別の例については、ES モジュールと CommonJS ファイル実行の違いに関する公式 Node.js ドキュメントを参照してください。

以上がイベントループを使用した mjs と cjsの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。