Estoy tratando de hacer una aplicación meteorológica simple basada en Node.js, como esta . Mi problema es que todos los mecanismos que veo se basan en promesas y no entiendo el concepto.
Entonces, el código que veo en todas partes es como:
yrno.getWeather(LOCATION).then((weather) => { weather.getFiveDaySummary().then((data) => console.log('five day summary', data)); weather.getForecastForTime(new Date()).then((data) => console.log('current weather', data)); }) .catch((e) => { console.log('an error occurred!', e); });Sin embargo, no pude encontrar una manera de resolver estas promesas y guardar el resumen de cinco días en una variable para su uso posterior.
¿Cómo procedo?
gracias, robin
Asigne la Promise devuelta por yrno.getWeather(LOCATION) a una variable.
Use Promise.all() para obtener resultados de las llamadas weather.getFiveDaySummary() y weather.getForecastForTime(new Date()) .
.then() al resultado de la llamada para obtener los datos en el .then() inicial y posterior encadenado al identificador de variable que devolvió los valores iniciales de Promise .
let weatherData = yrno.getWeather(LOCATION).then(weather => { // note `return`, alternatively omit `return` and `{`, `}` at arrow function // .then(weather => Promise.all(/* parameters */)) return Promise.all([weather.getFiveDaySummary() , weather.getForecastForTime(new Date())]); }); weatherData // `results` is array of `Promise` values returned from `.then()` // chained to `yrno.getWeather(LOCATION).then((weather)` .then(results => { let [fiveDaySummary, forecastForTime] = results; console.log('five day summary:', fiveDaySummary , 'current weather:', forecastForTime); // note `return` statement, here return results }) .catch(e => { // `throw` `e` here if requirement is to chain rejected `Promise` // else, error is handled here console.log('an error occurred!', e); }); // weatherData // .then(results => { // do stuff with `results` from first `weatherData` call }) // .catch(e => console.log(e));Una alternativa al uso de promesas directamente es usar await/async.
// weather.js const yrno = require('yr.no-forecast')({ version: '1.9', // this is the default if not provided, request: { // make calls to locationforecast timeout after 15 seconds timeout: 15000 } }); const LOCATION = { // This is Dublin, Ireland lat: 53.3478, lon: 6.2597 }; async function getWeather() { let weather = await yrno.getWeather(LOCATION); let fiveDaySummary = await weather.getFiveDaySummary(); let forecastForTime = await weather.getForecastForTime(new Date()); return { fiveDaySummary: fiveDaySummary, forecastForTime: forecastForTime, } } async function main() { let report; try { report = await getWeather(); } catch (e) { console.log('an error occurred!', e); } // do something else... if (report != undefined) { console.log(report); // fiveDaySummary and forecastForTime } } main(); // run itpuedes ejecutar esto (node.js 7) con:
node --harmony-async-await weather
Puede usar await/async en objetivos más antiguos usando Babel o Typescript para transpilarlo por usted.
Bonificación (basado en sus comentarios): no lo haría de esta manera, pero solo para mostrarle que se puede hacer:
const http = require('http'); const port = 8080; http.createServer( async function (req, res) { let report = await getWeather(); // see above res.writeHead(200, { 'Content-Type': 'text/plain' }); res.write("" + JSON.stringify(report.fiveDaySummary)); res.end('Hello World\n'); }) .listen(port); nuevamente con node --harmony-async-await weather o transpile.