首页 > 解决方案 > 如果 .then() 不起作用,如何获取 [[PromiseValue]] 的内容?

问题描述

情况是:我有一个函数数组cities,它为每个函数getCityForecast获取预测并将接收到的转换数据返回为所需的格式。我需要将它们保存到数组中,并将这个数组保存statecomponent.

this.state = {
      cities: [
        'Санкт-Петербург',
        'Москва',
        'Казань',
        'Самара',
        'Красноярск',
        'Чита',
        'Челябинск',
        'Оренбург',
        'Ростов-на-Дону',
        'Орск'
      ],

      cityObjects: []
    };

    this.getCityForecast = this.getCityForecast.bind(this);
    this.renderCities = this.renderCities.bind(this);
}

getForecastData = async (cityKey, cityName) => {
    const apiKey = 'ExAmPlEkEy';
    const forecastUri = 'http://dataservice.accuweather.com/forecasts/v1/daily/1day/';
    const uriToFetch = `${forecastUri}${cityKey}?language=ru&metric=true&details=true&apikey=${apiKey}`;
    try {
      let response = await fetch(uriToFetch);
      if(response.ok) {
        let jsonResponse = await response.json(); // Converts into JSON
        if (jsonResponse.DailyForecasts) {
          let cityData = jsonResponse.DailyForecasts.map(forecast => ({ //Data converted here into a convenient object
            icon: forecast.Day.Icon,
            iconPhrase: forecast.Day.IconPhrase,
            tempValue: forecast.Temperature.Maximum.Value,
            tempUnit: forecast.Temperature.Maximum.Unit,
            cityKey: cityKey,
            cityName: cityName
          })   
        );

        let renderCity = cityData.map(city => ( // Presented in React.js manner
              <div
                className="weather"
                key={city.cityKey}>
                <h1>{city.cityName}</h1>
                <img
                  src={`http://apidev.accuweather.com/developers/Media/Default/WeatherIcons/${city.icon}-s.png`}
                  alt={city.iconPhrase}
                  className="weathericon" />
                <h2>{`Температура: ${city.tempValue}°${city.tempUnit}`}</h2>
              </div>
            )
          );

          return renderCity; // Retuns a formatted city forecast
        } else {
          return [];
        }
      }
      throw new Error('Forecast request failed!');
    } catch (error) {
      console.log(error);
    }
  }

renderCities = () => { // applies this.getCityForecast() to the array of city names
    if(this.state.cities) {
      const cityObj = Promise.all(this.state.cities
        .map(city => this.getCityForecast(city)))
          .then(promiseResp => (promiseResp)) // CASE ONE
          /*.then(val => (val))*/ // CASE TWO <-- Not the above promise's value
          .catch(e => {console.log(e)});
      console.log(cityObj); // Save response to this.cityObjects
    }
  }

所以问题是CASE ONE它返回:

_proto__: Promise
[[PromiseStatus]]: "resolved"
[[PromiseValue]]: Array(2) // <-- I need this content
  0: [{…}]
  1:  [{…}]
  length: 2
  __proto__:  Array(0)

CASE TWO我有:

__proto__: Promise
[[PromiseStatus]]: "pending"
[[PromiseValue]]: undefined

我如何获得CASE ONE's 的[[PromiseValue]]内容?

标签: javascriptreactjspromise

解决方案


你应该做renderCities一个异步函数和await承诺:

renderCities = async () => { // applies this.getCityForecast() to the array of city names
    if(this.state.cities) {
      const cityObj = await Promise.all(this.state.cities
        .map(city => this.getCityForecast(city)))
          .catch(e => {console.log(e)});
      console.log(cityObj); // Save response to this.cityObjects
    }
  }

.then(promiseResp => (promiseResp))或者.then(val => (val))实际上什么都不做——你只是将 promise 中的值映射到自身。

另请参阅如何访问承诺的价值?


推荐阅读