在React Redux中分派动作之前等待多个Axios调用

时间:2019-08-23 22:01:46

标签: javascript reactjs redux axios redux-thunk

我有一个React Redux应用程序,需要使用axios调用多个API端点,等待这些API调用的结果,然后调度一个动作。

问题::在我当前的以下实现中,看来redux-thunk正在分派动作,而axios返回的是API调用结果。

我们如何解决问题,以便在分派操作之前等待3个axios调用返回所有3个结果?

/src/actions/index.js

const axios = require('axios');
import { GET_PRICES } from './types';

export function getSpotPrice(crypto) {
    axios.get(`https://api.coinbase.com/v2/prices/${crypto}-USD/spot`).then( (response) => {
        return parseFloat(response.data.data.amount);
    }).catch((err) => {
        console.log(err)
    })
}

function timeout(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
}

export function getSpotPrices() {
    return function(dispatch) {
        const cryptoList = ['BTC', 'ETH', 'XRP'];
        let cryptoRates = {}

        cryptoList.forEach(async (crypto, i) => {
            await timeout(1000);        // Wait 1 sec between API calls
            cryptoRates[crypto] = await getSpotPrice(crypto);
        });

        dispatch({
            type: GET_PRICES,
            payload: cryptoRates,
        })
        console.log('cryptoRates:', cryptoRates)        // returns {}
    }
}

2 个答案:

答案 0 :(得分:3)

您需要使包含函数async在分派之前等待所有异步调用,像这样:

export function getSpotPrices() {
    return async function(dispatch) {
        const cryptoList = ['BTC', 'ETH', 'XRP'];
        let cryptoRates = {}

        for(let crypto of cryptoList) {
            await timeout(1000);        // Wait 1 sec between API calls
            cryptoRates[crypto] = await getSpotPrice(crypto);
        }

        dispatch({
            type: GET_PRICES,
            payload: cryptoRates,
        });
        console.log('cryptoRates:', cryptoRates);
    }
}

答案 1 :(得分:1)

我相信您可以执行的另一种方法是使用Promise.all方法。数组中的所有promise都解决后,将调用该语句。

var promise1 = Promise.resolve(3);
var promise2 = 42;
var promise3 = new Promise(function(resolve, reject) {
  setTimeout(resolve, 100, 'foo');
});

Promise.all([promise1, promise2, promise3]).then(function(values) {
  console.log(values);
});