2015-11-11 6 views
-1

У меня есть это небольшое приложение Express.js, которое принимает POST-запрос с «городом» как тело. Приложение обрабатывает вызов и использует для этого внешнюю службу. Я попытался разделить логику «Pure» с REST-контроллером, чтобы поддерживать ее в чистоте, но почему-то, когда я называю метод «погода», он ничего не вернет, даже если строка, проходящая, является действительной объект. Я предполагаю, что есть проблема с асинхронным вызовом, но я не вижу себя в позиции, чтобы решить ее сам.Почему моя «требуемая» функция ничего не возвращает?

RestController.js

module.exports = (function() { 
    var router = require('express').Router() 
    var bodyParser = require('body-parser') 
    var weather = require('./weather') 

    router.use(bodyParser.urlencoded({ extended: true })) 
    router.use(bodyParser.json()) 

//TODO DATABASE CONNECTION 

    //REST CONTROLLER 
    router.get('/', function(req, res) { 
    res.json({response: 'Hello world!'}) 
    }) 

    router.post('/weather', function(req, res) { 
    var r = weather(req.body.city) 
     res.send(r) 
    }) 

    return router 
})(); 

weather.js

var request = require('request') 

module.exports = function(loc) { 
    request('http://api.openweathermap.org/data/2.5/weather?q='+loc+'&units=metric&APPID=API_TOKEN', function(err , ires) { 
    if(!err) { 
     json = JSON.stringify({temp: JSON.parse(ires.body).main.temp, name: JSON.parse(ires.body).name}) 
     console.log(json) 
     return json 
    } 
    else { 
     return err 
    } 

    }) 
}; 

С наилучшими пожеланиями,

Tim

ответ

1

Вы должны пройти обратный вызов вашей функции погоды, так что вы можете справиться с этим когда он будет завершен. например

module.exports = function(loc, callback) { 
    request('http://api.openweathermap.org/data/2.5/weather?q='+loc+'&units=metric&APPID=API_TOKEN', function(err , ires) { 
    if(!err) { 
     json = JSON.stringify({temp: JSON.parse(ires.body).main.temp, name: JSON.parse(ires.body).name}) 
     console.log(json) 
     callback(null, json) 
    } else { 
     callback(err) 
    } 

    }) 
}; 

Затем используйте следующие в вашей программе:

router.post('/weather', function(req, res) { 
    var r = weather(req.body.city, function (e, result) { 
     if (e) return res.status(500).send({error: e}); 
     res.send(result) 
    }) 
}) 

Это стандартный шаблон узла (есть лучшие из них). Узел не блокируется, поэтому он не будет ждать завершения вашего запроса погоды. Он, в конце концов, обработает его в цикле событий после вызова вызова.

+1

Ничего себе, это работает просто отлично! Я понимаю, почему это не сработало раньше. Так просто .. :(Во всяком случае, ура! – timschmolka

+0

рад помочь :) – chriskelly