对象键“未定义”

时间:2018-08-12 02:22:28

标签: javascript arrays api object axios

我从API获得一个对象,并在其中使用其他API响应创建新对象,例如:

API响应1:Obj: {a: 1, b: 2}

API响应2:3

创建对象:Obj.c = 3

最终结果:对象:{a: 1, b: 2, c: 3}

问题:

console.log(Obj) return Obj: {a: 1, b: 2, c: 3}

console.log(Obj.c) return undefined

当尝试在属性中的console.log之后给出.map时,我没有得到,我无法访问创建的属性,返回undefined。但是,当我在任何对象上赋予console.log时,创建的属性就在那里。

我的代码:

async getGeneralInfo(token, seed) {
    try {
        API_HEADER.headers.Authorization = token;
        let responseAvaliableCoins = await axios.get(
            BASE_URL + "/coin",
            API_HEADER
        );

        let avaliableCoins = responseAvaliableCoins.data.data.coins;

        avaliableCoins.map(async (coin, index) => {
            if (coin.status === "active") {
                let responseCreateAddress = await axios.post(
                    BASE_URL + "/coin/" + coin.abbreviation + "/address",
                    { seed },
                    API_HEADER
                );

                avaliableCoins[index].address =
                    responseCreateAddress.data.data.address;

                let responseBalance = await axios.get(
                    BASE_URL +
                    "/coin/" +
                    coin.abbreviation +
                    "/balance/" +
                    coin.address,
                    API_HEADER
                );

                avaliableCoins.token = responseBalance.headers[HEADER_RESPONSE];
                avaliableCoins[index].balance = responseBalance.data.data;
            } else {
                avaliableCoins[index].address = undefined;
                avaliableCoins[index].balance = undefined;
            }
        });

        console.warn(avaliableCoins[0].balance); //undefined
        console.warn(avaliableCoins[0]["balance"]); //undefined
        console.warn(avaliableCoins[0].address); //undefined
        console.warn(avaliableCoins[0]["address"]); //undefined

        console.warn("avaliableCoins", avaliableCoins); //All objects are here
        console.warn("avaliableCoins[0]", avaliableCoins[0]); //All objects are here

        return avaliableCoins;
    } catch (error) {
        internalServerError();
        return;
    }
}

更新----- enter image description here

1 个答案:

答案 0 :(得分:1)

map中使用的函数是异步的。

现在在所有硬币上都调用map,并且在所有异步数据可以返回之前,代码已经移至console.warn()调用。

availableCoins最终将在返回时使用所有异步数据进行更新,但是这里存在竞争条件,因为代码没有明确地等待发生这种情况。

以下是推荐的方法:

  • async中的每个map调用中返回修改后的项,这将返回Promise,该函数将在async函数完成后解析为修改后的项。
  • li>
  • 使用Promise.all()等待Promises的数组
  • 返回结果数组

以下是简化版,介绍了该方法:

const getData = () => {
  return Promise.resolve('data');
}

export const getGeneralInfo = async () => {
  let avaliableCoins = [
    { a: 1 },
    { a: 2 }
  ]

  const promises = avaliableCoins.map(async (coin) => {
    let response = await getData();
    // modify coin and return it
    coin.data = response;
    return coin;
  });

  const updatedCoins = await Promise.all(promises);

  console.log(updatedCoins); // [{a: 1, data: 'data'}, {a: 2, data: 'data'}]

  return updatedCoins;
}

您修改后的函数将如下所示:

async getGeneralInfo(token, seed) {
  try {
    API_HEADER.headers.Authorization = token;
    let responseAvaliableCoins = await axios.get(
      BASE_URL + "/coin",
      API_HEADER
    );

    let avaliableCoins = responseAvaliableCoins.data.data.coins;

    const promises = avaliableCoins.map(async (coin) => {
      if (coin.status === "active") {
        let responseCreateAddress = await axios.post(
          BASE_URL + "/coin/" + coin.abbreviation + "/address",
          { seed },
          API_HEADER
        );

        coin.address =
          responseCreateAddress.data.data.address;

        let responseBalance = await axios.get(
          BASE_URL +
          "/coin/" +
          coin.abbreviation +
          "/balance/" +
          coin.address,
          API_HEADER
        );

        coin.token = responseBalance.headers[HEADER_RESPONSE];
        coin.balance = responseBalance.data.data;
      } else {
        coin.address = undefined;
        coin.balance = undefined;
      }
      return coin;
    });

    availableCoins = await Promise.all(promises);

    console.warn(avaliableCoins[0].balance); //undefined
    console.warn(avaliableCoins[0]["balance"]); //undefined
    console.warn(avaliableCoins[0].address); //undefined
    console.warn(avaliableCoins[0]["address"]); //undefined

    console.warn("avaliableCoins", avaliableCoins); //All objects are here
    console.warn("avaliableCoins[0]", avaliableCoins[0]); //All objects are here

    return avaliableCoins;
  } catch (error) {
    internalServerError();
    return;
  }
}