在循环和嵌套的promises中发布请求

问题描述 投票:-1回答:1

我想要一些帮助!

我正在尝试为每个数组元素发布一个post请求。

问题是我需要从每个post响应中累积答案,然后将count数组返回给调用函数。我认为计数返回的基本问题是0(初始化),换句话说,发布请求尚未完成,答案已经返回。

我也认为我的代码太嵌套了我需要帮助来简化请求

谢谢

function gt({ username, startDate, endDate }) {
  const query = '....' //never mind here 

  client.request(query, { username:arguments[0],
    startDate:arguments[1],
    endDate:arguments[2]})
      .then((response)=>{
        //response here is ok and what i expect then i want to send the response for proccesing and get the answer back in categories

        let count = getCategories(response["transactions"]);
// here is the wanted result should be in the returned answer
        console.log(count);
      })
      .catch((err)=>{console.log(err)});

}

function getCategories(transactions){

  let count = CATEGORIES; /// some json with keys and values
  Object.keys(count).forEach(v => count[v] = 0)  /// zero the values

  for (var i=0;i<transactions.length;i++){
    let transaction= transactions[i];
    axios.post(SERVER_URL, {
      transDescription: transaction["description"]
    })
        .then( function (response) {
          let category = response.data["transactionCategory"];
          console.log(category)
          count[category]+= transaction["amount"];}) //accumulating in count and then return when loop finishes
        .catch(function (error) {
          console.log(error);
        });
  }

  return count;
}

调用gt函数:


gt('some username','some date','some date'); 

// i expect to get the count variable here and print it


javascript node.js es6-promise
1个回答
0
投票

实际上,你的for循环在任何axios请求完成之前完成并且他们的承诺解决了。

此外,您可能希望您的gt函数实际返回一些东西:计数的承诺。

我建议使用asyncawait,这对于具有异步代码的循环非常实用。

注意:Promise.all是另一种选择,但是你几乎可以在几乎同时发送许多请求。

function gt({ username, startDate, endDate }) {
    const query = "...";

    return client.request(query, {
//  ^^^^^^    
        username:arguments[0],
        startDate:arguments[1],
        endDate:arguments[2]
    }).then((response) => {
        let categories = getCategories(response["transactions"]);
        console.log(categories);
        return categories; // <----
    }).catch((err) => {
        console.log(err);
    });
}

async function getCategories(transactions) {
//^^^
    let count = CATEGORIES;
    Object.keys(count).forEach(v => count[v] = 0);

    for (var i = 0; i < transactions.length; i++) {
        let transaction = transactions[i];
        let response = await axios.post(SERVER_URL, {
//      ^^^^^^^^^^^^^^^^^^^^
            transDescription: transaction["description"]
        });
        let category = response.data["transactionCategory"];
        console.log(category)
        count[category] += transaction["amount"];
    }
    return count;
}

CATEGORIES需要另一条评论:你的代码会改变那个对象结构。如果再次调用此函数并再次使用CATEGORIES,则这可能是“危险的”:在该情况下,先前的结果将被覆盖。每次初始化count时,实际上要复制一份会更为谨慎:

let count = {...CATEGORIES};
© www.soinside.com 2019 - 2024. All rights reserved.