承诺然后阻止执行,然后再执行发布请求吗?

时间:2019-07-17 19:51:40

标签: node.js reactjs asynchronous callback axios

我正在使用axios向我的Nodejs后端发出Post请求,以使用AWS S3来为我需要的特定数据拉出Urls(与问题并不完全相关,但与上下文有关)。

在后端,我有一个包含12个条目的数组,每个元素都初始化为“测试”。然后,根据前端的json更新数组中的特定元素。更新一个这样的元素后,我立即console.log整个数组,它正确地具有更新的数组。当我在后端返回之前最后一次控制台控制台整个阵列时,所有条目都是“测试”,但我知道这可能是因为console.log不同步。但是,当我将该数组返回给frontend和console.log时,该数组仍然是所有12个“测试”,这使我相信'then'块在Post请求完成之前就已经执行了(这令人困惑) 。我不确定该怎么做,因为在前端进行其他数据验证之前,我需要正确的数组。任何建议将不胜感激。

我尝试过将发布请求放在一个单独的函数中并返回那个诺言,但这也不起作用。

handleSubmit(event) {
event.preventDefault();
//other code before
let json=JSON.stringify(data);
let post_data={json_data:json}

 this.grabData(post_data)
  .then((response) => {
    console.log(response)
    var myObj = JSON.parse(response.data.json_data);
    console.log(myObj.length)
    var i;
    //Should output that certain elements have been changed, but all show up as 'test' still
    for (i = 0; i < 12; i++) {
      console.log("element " + i + " is: " + myObj[i])
    }
    this.state.urls = myObj;
    var z;
    for (z = 0; z < 12; z++) {
      if (this.state.urls[z] === "test") {
        this.state.urls.splice(z, 1);
        z = z - 1;
      }
    }
    //The state.urls should not be empty after the splicing, but it is because all elements are still 'test' 
    console.log("After splicing: " + this.state.urls)
  });
}

grabData(post_data) {
  return axios.post('/getCharts', post_data)
}

在后端:

  app.post('/getCharts', (req, res) => {
  var obj = JSON.parse(req.body.json_data)
  let getThese = req.body[0]
  var urls = ["test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test"];
  var i;
  var year = new Date().getFullYear();
  console.log(year)

  let jan = ''
  let feb = ''
  let mar = ''
  let apr = ''
  let may = ''
  let jun = ''
  let jul = ''
  let aug = ''
  let sep = ''
  let oct = ''
  let nov = ''
  let dec = ''

  for (i = 0; i < obj.length; i++) {
    if (obj[i] == 1) {
      key = 'charts/pieChart' + year + '-01-01.png'
      console.log(key)
      var params = {Bucket: bucketName, Key: key}

      s3.headObject(params, function (err, metadata) {
        if (!err) {
          urls[0] = s3.getSignedUrl('getObject', params);
        }
      });
    }
    if (obj[i] == 2) {
      key = 'charts/pieChart' + year + '-02-01.png'
      console.log(key)
      var params = {Bucket: bucketName, Key: key}

      s3.headObject(params, function (err, metadata) {
        if (!err) {
          urls[1] = s3.getSignedUrl('getObject', params);
        }
      });
    }
    if (obj[i] == 3) {
      key = 'charts/pieChart' + year + '-03-01.png'
      console.log(key)
      var params = {Bucket: bucketName, Key: key}

      s3.headObject(params, function (err, metadata) {
        if (!err) {
          urls[2] = s3.getSignedUrl('getObject', params);
          //This outputs a correctly updated array
          console.log(urls)
        }
      });
    }
    //This if block is repeated 12 times, up to obj[i] = 12, so removing for sake of simplicity
  }

  var i2;
  //This array prints out 12 'test' but I understand it's because console.log is executed async
  for (i2 = 0; i2 < 12; i2++) {
    console.log("urls" + i2 + " is: " + urls[i2])
  }

  let json=JSON.stringify(urls);

  let post_data={json_data:json}

  res.setHeader('Content-Type', 'application/json');
  res.send(post_data);
});

1 个答案:

答案 0 :(得分:0)

我的朋友,Obj for循环是讨厌的代码,哈哈。for循环的原因是只做一次。我清理了您的代码。它应该工作。但是,如果不是这样,这就是基本思想。

 app.post('/getCharts', (req, res) => {
  var obj = JSON.parse(req.body.json_data)
  let getThese = req.body[0]
  var urls = ["test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test"];
  var i;
  var year = new Date().getFullYear();
  console.log(year)

  let jan = ''
  let feb = ''
  let mar = ''
  let apr = ''
  let may = ''
  let jun = ''
  let jul = ''
  let aug = ''
  let sep = ''
  let oct = ''
  let nov = ''
  let dec = ''

        let uploads = 0;
    const finishedUpload = () => {
        uploads++;
        if (uploads === obj.length) {
              var i2;
              //This array prints out 12 'test' but I understand it's because console.log is executed async
              for (i2 = 0; i2 < 12; i2++) {
                console.log("urls" + i2 + " is: " + urls[i2])
              }

              let json=JSON.stringify(urls);

              let post_data={json_data:json}

              res.setHeader('Content-Type', 'application/json');
              res.send(post_data);
        }
    }

  for (i = 0; i < obj.length; i++) {
    const myKey = i+1;
    if (obj[i] == myKey) {
      key = 'charts/pieChart' + year + '-0' + myKey +'-0' + myKey +'.png'
      console.log(key)
      var params = {Bucket: bucketName, Key: key}

      s3.headObject(params, function (err, metadata) {
        if (!err) {
          urls[i] = s3.getSignedUrl('getObject', params);
          finishedUpload()
        }
      });
    }
  }

});