我如何解决Node.js中的承诺?

时间:2017-04-29 17:18:35

标签: javascript node.js promise

我正在尝试基于Node.js创建一个简单的天气应用程序,例如this one。我的问题是,我看到的每一种机制都是基于承诺,我不明白这个概念。

所以,我到处看到的代码就像:

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);
    });

但是,我无法找到解决这些承诺的方法,并将五天的摘要保存到变量中供以后使用。

我该如何处理?

谢谢, 罗宾

2 个答案:

答案 0 :(得分:0)

Promise调用返回的yrno.getWeather(LOCATION)分配给变量。

使用Promise.all()返回weather.getFiveDaySummary()weather.getForecastForTime(new Date())来电的结果。

.then()链接到调用的结果,以便将初始和后续.then()处的数据链接到返回初始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));

答案 1 :(得分:0)

直接使用promises的另一种方法是使用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 it

你可以用:

运行它(node.js 7)

node --harmony-async-await weather

您可以使用Babel或Typescript为旧目标使用await / async。

奖金(基于您的评论) - 我不会这样做,但只是为了向您展示它可以做到:

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);

enter image description here

再次使用node --harmony-async-await weather或进行转换。