【问题标题】:How to know when node.js express server is up and ready to use如何知道 node.js express 服务器何时启动并准备好使用
【发布时间】:2013-08-16 23:33:47
【问题描述】:

有一个应用程序,我想在其中启动 node express 服务器,然后在服务器启动后自动在同一台机器上启动浏览器。如何查询服务器是否已启动并准备就绪?我真的希望在 .listen 调用上有某种回调,但似乎没有。我可以等待比我预期的时间更长的时间,但这是在现场的设备上进行的,所以我要么必须等待一段荒谬的时间,以确保在启动浏览器之前我已经启动并运行或者如果页面加载不正确,让用户足够聪明地点击刷新。这两个对我来说都不是好选择。 . .

我在线阅读了 API,但没有看到类似的内容。肯定有一个我不知道的技巧可以做到这一点。

如果节点 HTTP api(它有一个回调并告诉我监听事件)是 express 对象的基础,那么可能有一个没有记录的 express 调用 listen 的回调选项。或者也许我应该知道它就在那里。

任何帮助将不胜感激。

【问题讨论】:

    标签: javascript node.js express


    【解决方案1】:

    Express app.listen 函数确实支持回调。它将您传入的参数映射到 http.listen 调用。

    app.listen = function(){
      var server = http.createServer(this);
      return server.listen.apply(server, arguments);
    };
    

    所以您可以拨打:app.listen(port, callback);

    或者你可以直接使用http.listen。

    var app = require('express')(),
        server = require('http').createServer(app);
    
    server.listen(80, function() {
        console.log('ready to go!');
    });
    

    【讨论】:

    • 在第二个代码块中,如果 server.listen 失败了怎么办?
    • 您将添加一个错误侦听器。比如:server.listen(80).on('error', function(err) { });
    【解决方案2】:

    您可以使用http.listen 方法,该方法具有在服务器准备好后触发的回调函数:

    http.createServer(app).listen(app.get('port'), function () {
        console.log('Printed when ready!!!');
    });
    

    参见 Node.js 的官方参考:

    http://nodejs.org/api/all.html#all_server_listen_port_hostname_backlog_callback

    http://nodejs.org/api/all.html#all_server_listen_path_callback_1

    http://nodejs.org/api/all.html#all_server_listen_handle_callback_1

    【讨论】:

      【解决方案3】:

      正如许多人所提到的,listen 函数(在 express 应用程序或 http 服务器上,都支持它)确实支持回调,这将使您的节点进程知道它何时正在侦听。

      因此,如果您打算从 express 应用程序中启动浏览器,请在此处执行,这样就很好了。但是,如果您从外部脚本启动 express 应用程序,然后希望该外部脚本打开浏览器,则节点回调并不能真正为您带来任何好处。

      在标准输出上等待一些神奇的字符串并不是仅仅等待一个好的 HTTP 响应的改进。您也可以使用 curl 的 try/backoff/timeout 循环,直到您获得成功的响应。

      【讨论】:

        【解决方案4】:

        您可以在服务器启动后触发自定义事件:

        // server.js
        const express = require('express');
        const app = express();
        
        modeule.export = app;
        app.listen(3000, () => {
           app.emit('listened', null)
        });
        

        在单独的模块中,应用可以监听您的自定义事件:

        // custom.js
        const server = require('server.js');
        server.on('listened', function() {
          console.log('The server is running!');
        });
        

        【讨论】:

        • 当调用listen 时会发出此事件,但并不表示服务器已准备好并正在侦听。为此,您应该执行以下操作:app.listen(3000, () => app.emit('listened', null));
        • @Daveyjoe 你说得对,谢谢!我更新了我的答案。
        【解决方案5】:
        server.on('listening', function() {
          resolve();//I added my own promise to help me await
        });
        

        The Listening event 为我工作。注意我添加了我自己的 Promise。我想你可以通过向这个监听器添加一个入口点来获得类似的结果而无需承诺。

        注意,我尝试了更直观的server.on('listen'),但没有成功。运行节点 6.9.1

        【讨论】:

        • 奇怪的是它起作用了。 listening 不是事件而是函数。
        【解决方案6】:

        使用async/await 语法,这可以通过将服务器启动包装在一个promise 中来完成,因此您可以在运行其他任何东西之前等待它启动:

        import express from 'express';
        import http from 'http';
        
        const app = express();
        let server: http.Server;
        const startServer = async (): Promise<void> => {
          return new Promise((resolve, _reject) => {
            server = app.listen(3000, () => {
              console.log('Express server started');
              resolve();
            });
          });
        };
        
        await startServer();
        // here the server is started and ready to accept requests
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-10-19
          • 2017-07-06
          • 2011-06-01
          • 2018-05-05
          • 2018-07-17
          • 2012-12-12
          • 2023-03-21
          • 1970-01-01
          相关资源
          最近更新 更多