我使用axios POST method使用连续的then通过API发布多个内容。

为了修复硬编码的then,我尝试使用for循环(使用let,for..of,Promise.all等),但无法正常工作

File "C:\Python\Python3.6.3\lib\wsgiref\simple_server.py", line 35, in close
self.status.split(' ',1)[0], self.bytes_sent
AttributeError: 'NoneType' object has no attribute 'split'


错误(Django后端)。

这是源代码(.vue文件)。

//defaultHttpClient is an axios call

const labelList = this.newLabel.text.split(" ");
this.copiedLabels = JSON.parse(JSON.stringify(this.newLabel));

async function putLabel(i, response, newLabel, copiedLabels, labels){
     copiedLabels.text = newLabel.text.split(" ")[i]
     await defaultHttpClient.post(`/v1/projects/${response.data.id}/labels`, copiedLabels)
      //API call
      }


//tried to make multiple API calls but this was the only way to make it possible.

      defaultHttpClient.post('/v1/projects', payload)
        .then((response) => {
          window.location = `/projects/${response.data.id}/docs/create`;
          return response;
        })
        .then((response)=> {
          putLabel(0, response, this.newLabel, this.copiedLabels, this.labels);
          return response;
        })
        .then((response)=> {
          putLabel(1, response, this.newLabel, this.copiedLabels, this.labels);
          return response;
        })
        .then((response)=> {
          putLabel(2, response, this.newLabel, this.copiedLabels, this.labels);
          return response;
        })


我们如何简化硬编码的then或使其更好地工作?

最佳答案

您可以使用asyncawait来简化:

async function someFunction() {

      try {
          let response = await defaultHttpClient.post('/v1/projects', payload)
          await putLabel(0, response, this.newLabel, this.copiedLabels, this.labels);
          await putLabel(1, response, this.newLabel, this.copiedLabels, this.labels);
          await putLabel(2, response, this.newLabel, this.copiedLabels, this.labels);
          window.location = `/projects/${response.data.id}/docs/create`;
      } catch(e) {
          // put some error handling code here
      }
 }




正是为了让您理解,您的原始代码根本无法使用。在所有window.location调用都没有执行之前,putLabel()会更改当前页面。在将window.location设置到新页面之前,您需要完成所有想要完成的工作。

另外,您所有的.then()处理程序都没有编码为按正确的顺序执行,因为它们没有一个等待每个putLabel()完成。为此,您必须使用它们返回的承诺,但您只是忽略了这一点。



您可以将putLabel进一步简化为:

function putLabel(i, response, newLabel, copiedLabels, labels) {
     copiedLabels.text = newLabel.text.split(" ")[i]
     return defaultHttpClient.post(`/v1/projects/${response.data.id}/labels`, copiedLabels)
      //API call
}


重要的是要记住,await会暂停函数的内部执行,但是async函数在击中第一个await时仍会立即返回promise。因此,您在await中的putLabel()并没有完成任何事情,也没有阻止putLabel()在完成.post()调用之前返回。



似乎也没有特别的原因,您的putLabel()调用必须顺序执行,其中第二个等待第一个完成,并且它们可以全部并行运行。如果是这种情况,则可以这样运行它们:

async function someFunction() {

      try {
          let response = await defaultHttpClient.post('/v1/projects', payload)
          await Promise.all([
              putLabel(0, response, this.newLabel, this.copiedLabels, this.labels),
              putLabel(1, response, this.newLabel, this.copiedLabels, this.labels),
              putLabel(2, response, this.newLabel, this.copiedLabels, this.labels)
          ]);
          window.location = `/projects/${response.data.id}/docs/create`;
      } catch(e) {
          // put some error handling code here
      }
 }

关于javascript - 如何简化异步axios post方法的多个“then”?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57302396/

10-10 05:09