如何从Hapi处理程序返回一个承诺

时间:2017-07-20 10:29:30

标签: node.js hapijs

我有一个非常简单的Hapi服务器,它返回一个Promise,当解析时调用reply(),我知道这可以通过它的文档来实现:https://hapijs.com/api#route-handler

问题是Promise似乎没有得到解决(因此我没有收到回复),直到我刷新页面几次或很长一段时间。 check_ips返回的承诺按预期工作,因此它似乎与Hapi如何处理它有关。

const Hapi = require('hapi');
const ping = require('net-ping')

const server = new Hapi.Server({ debug: { request: ['error'] } });
const port = process.env.PORT || 8080;
server.connection({ port: port, host: 'localhost' });

const session = ping.createSession();

check_ips = function(ips) {
    var pings = []

    for (var i = 0; i < ips.length; i++) {
        pings.push(new Promise(function(fulfill, reject) {
            session.pingHost(ips[i], function(err, target)  {
                if (err) {
                    if (err instanceof ping.RequestTimedOutError)
                        fulfill(false)
                    else
                        reject(err)
                } else {
                    fulfill(true)
                }
            })
        }))
    }

    return Promise.all(pings).then(function(results) {
        response = {}
        for (var i = 0; i < ips.length; i++) {
            response[ips[i]] = results[i]
        }

        return(JSON.stringify(response))
    })
}

server.route({
    method: 'GET',
    path: '/check_ips/{ips}',
    handler: function(req, reply) {
        if (!req.params["ips"]) {
            return reply({"error": "No IPs received"})
        }

        ips = req.params["ips"].split(",")
        return check_ips(ips).then(reply)
    }
});                                                                                                                         

server.start(function(err) {
    if (err) {
        throw err;
    }
    console.log(`Server running at: ${server.info.uri}`);
});

1 个答案:

答案 0 :(得分:0)

不确定问题是否仍然与OP相关。

该问题可能与Hapijs或Node.js无关。似乎与拒绝处理有关,即路由中没有catch

我已经重写了您的函数,没有副作用,以确保它总是返回。

const pingHost = (ip, cb) => {
    cb(ip % 3 === 0 && {});
};

const check_ips = function (ips) {
    return Promise.all(ips.map((ip) => {
        return new Promise((fulfill, reject) => {
            pingHost(ip, (err, target) => {
                if (err) {
                    if (err instanceof ping.RequestTimedOutError) {
                        fulfill(false);
                    } else {
                        reject(err);
                    }
                } else {
                    fulfill(true);
                }
            });
        });
    }))
        .then((results) => {
            return ips.reduce((acc, curr, i) => {
                return { ...acc, [curr]: results[i] }
            }, {});
        })
};

通常正常工作:

check_ips("1,2".split(",")).then(console.log); // {1: true, 2: true}

然后,它预期会失败:

check_ips("1,2,3".split(",")).then(console.log)

添加catch子句可防止其失败:

check_ips("1,2,3".split(",")).then(console.log).catch(console.error)

因此,为了正确修复它,我将开始调查pingHost返回的错误类型是什么,导致Promise被拒绝。