httpモジュールのcreateServerの引数について

投稿者: Anonymous

node.jsの勉強をしています。
httpモジュールのcreateServerの引数について質問です。
getFormClient関数は引数が2つありますが、
呼び出す側のhttp.createServer(getFormClient)は引数がありません。
これは、デフォルト引数ということで理解しました。

しかし、デフォルト引数であるならば、getFormClient関数の引数はundefinedになり、
res.writeHead(200, {'Content-Type': 'text/html'});などでエラーになるのではないでしょうか?

_x000D_

_x000D_

const http = require('http');_x000D_
const fs = require('fs');_x000D_
_x000D_
var server = http.createServer(getFormClient)_x000D_
function getFormClient(req, res){_x000D_
  fs.readFile('index.html', 'UTF-8',_x000D_
    (err, data) => {_x000D_
      res.writeHead(200, {'Content-Type': 'text/html'});_x000D_
      res.write(data);_x000D_
      res.end();_x000D_
    }_x000D_
  );_x000D_
}

_x000D_

_x000D_

_x000D_

解決

これは、デフォルト引数ということで理解しました。

いいえ、デフォルト引数ではありません。

そのコールバック関数 (getFormClient 関数) を呼び出すのは Node.js であり、内部で生成されたオブジェクトを引数として、当該コールバック関数を呼び出します。そのため、今回の場合デフォルト引数は関係がなく、 getFormClient 関数の引数は undefined になりません。念のため、 Node.js がどのように当該コールバック関数を呼び出すのかを、以下に粗く書いておきます。


http.createServer メソッドは、 http.Server クラスのインスタンスを返します[1]。この http.Server クラスは、 requestListener 関数 (getFormClient 関数) をリスナー関数として、 request イベントを登録します[2]。また、この処理は以下のコードから、 http.Server クラスのコンストラクタで行なわれていることがわかります[3]

node/http.js at 8507485fb242dfcaf07092414871aa9c185a28e4 · nodejs/node · GitHub[1]

function createServer(opts, requestListener) {
  return new Server(opts, requestListener);
}

http.createServer([options][, requestlistener])[2]

Returns a new instance of http.Server.

The requestListener is a function which is automatically added to the ‘request’ event.


node/_http_server.js at 8507485fb242dfcaf07092414871aa9c185a28e4 · nodejs/node · GitHub[3]

 function Server(options, requestListener) {
  if (!(this instanceof Server)) return new Server(options, requestListener);

  if (typeof options === 'function') {
    requestListener = options;
    options = {};
  } else if (options == null || typeof options === 'object') {
    options = { ...options };
  } else {
    throw new ERR_INVALID_ARG_TYPE('options', 'object', options);
  }

  this[kIncomingMessage] = options.IncomingMessage || IncomingMessage;
  this[kServerResponse] = options.ServerResponse || ServerResponse;

  net.Server.call(this, { allowHalfOpen: true });

  if (requestListener) {
    this.on('request', requestListener);
  }

  // 省略

実際に通信が確立され、 HTTP リクエストヘッダの解析が完了すると、 http.ServerResponse オブジェクトが生成されます。そしてその後、 request イベントに登録されたリスナー関数 (getFormClient 関数) が、 http.IncomingMessage オブジェクトと http.ServerResponse オブジェクトを引数として呼び出されます。[4]

node/_http_server.js at 458a38c904c78b072f4b49c45dda7c63987bb60b · nodejs/node · GitHub[4]

  if (req.headers.expect !== undefined &&
      (req.httpVersionMajor === 1 && req.httpVersionMinor === 1)) {
    if (continueExpression.test(req.headers.expect)) {
      res._expect_continue = true;

      if (server.listenerCount('checkContinue') > 0) {
        server.emit('checkContinue', req, res);
      } else {
        res.writeContinue();
        server.emit('request', req, res);
      }
    } else if (server.listenerCount('checkExpectation') > 0) {
      server.emit('checkExpectation', req, res);
    } else {
      res.writeHead(417);
      res.end();
    }
  } else {
    server.emit('request', req, res);
  }
  return 0;  // No special treatment.
}
回答者: Anonymous

Leave a Reply

Your email address will not be published. Required fields are marked *