28

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

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

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

任何帮助将不胜感激。

4

6 回答 6

39

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!');
});
于 2013-08-14T20:26:11.677 回答
8

您可以使用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

于 2013-08-14T20:28:56.223 回答
7

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

// 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!');
});
于 2016-01-19T09:12:20.837 回答
6

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

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

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

于 2013-08-14T20:35:47.803 回答
5
server.on('listening', function() {
  resolve();//I added my own promise to help me await
});

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

请注意,我尝试了更直观的方法server.on('listen'),但没有奏效。运行节点 6.9.1

于 2018-08-27T18:23:44.730 回答
0

使用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
于 2020-08-28T07:35:35.010 回答