访问数组元素时未定义,即使它存在

Getting undefined when accessing array element even though it exists

我正在异步操作创建器中使用 Axios 发送 HTTP 请求。我想用来调用同步动作创建器的参数存储在一个数组中。出于某种原因,当我尝试 console.log(args) (数组)时,我正确显示了数组,但是当我尝试 console.log(args[0]) (第一个元素)时,我得到了未定义。我不知道这个问题与什么有关。这是我的代码片段:

const initIngredients_Sync = (ingredientsData, error) => {
    console.log("sync args", ingredientsData, error);
    return({
        type: actionTypes.INIT_INGREDIENTS,
        initialState: ingredientsData,
        error
    });
};

export const initIngredients = () => {
    const args = [];
    return dispatch => {
        axiosInstance.get('/ingredients_prices.json')
            .then((response) => {
                const INGREDIENT_PRICES = response.data;
                
                const INGREDIENTS = (() => {
                    let ingredients = {};
                    for (const key in INGREDIENT_PRICES) {
                        if(key !== "base_price")
                        ingredients[key] = 0;
                    }
                    return ingredients;
                })();

                const ingredientsData = {
                    ingredients_prices: INGREDIENT_PRICES, 
                    ingredients: INGREDIENTS, 
                    totalPrice: INGREDIENT_PRICES.base_price
                };

                args.push(JSON.parse(JSON.stringify(ingredientsData)));
            })
            .catch((error) => {
                args.push(error);
            });

        console.log("args[0]", args[0]);

        args.length === 2
            ? dispatch(initIngredients_Sync(args[0], args[1])) // [ingredientsData, error]
            : dispatch(initIngredients_Sync(args[0], false)); // no error
    }
};

输出 console.log(args):

[]
   0: {ingredients_prices: {...}, ingredients: {...}, totalPrice: {...}}
   length: 1

输出 console.log(args[0]):

undefined

您在代码段中的控制台日志语句在 .then 回调之外。您应该检查此 once/after 您的 api 呼叫已解决,即在此行下方...

args.push(JSON.parse(JSON.stringify(ingredientsData)));
console.log(args[0]) // should print

Axios 是基于承诺的浏览器 HTTP 客户端,Node.js。

因此它的方法如 .get() 将异步解析。

An asynchronous model allows multiple things to happen at the same time. When you start an action, your program continues to run. When the action finishes, the program is informed and gets access to the result (for example, the data read from disk).

资源 - https://eloquentjavascript.net/11_async.html

这就是为什么您的 console.log 没有像您期望的那样输出结果。您可以通过在 then 方法中使用 args 调度操作来解决此问题。

const initIngredients_Sync = (ingredientsData, error) => {
  console.log("sync args", ingredientsData, error);
  return {
    type: actionTypes.INIT_INGREDIENTS,
    initialState: ingredientsData,
    error,
  };
};

export const initIngredients = () => {
  const args = [];
  return (dispatch) => {
    axiosInstance
      .get("/ingredients_prices.json")
      .then((response) => {
        const INGREDIENT_PRICES = response.data;

        const INGREDIENTS = (() => {
          let ingredients = {};
          for (const key in INGREDIENT_PRICES) {
            if (key !== "base_price") ingredients[key] = 0;
          }
          return ingredients;
        })();

        const ingredientsData = {
          ingredients_prices: INGREDIENT_PRICES,
          ingredients: INGREDIENTS,
          totalPrice: INGREDIENT_PRICES.base_price,
        };

        args.push(JSON.parse(JSON.stringify(ingredientsData)));

        // These lines moved to `then` method
        console.log("args[0]", args[0]);

        args.length === 2
          ? dispatch(initIngredients_Sync(args[0], args[1])) 
          : dispatch(initIngredients_Sync(args[0], false));
      })
      .catch((error) => {
        args.push(error);
      });
  };
};