使用 Vue.js 进行异步/等待 axios 调用

Posted

技术标签:

【中文标题】使用 Vue.js 进行异步/等待 axios 调用【英文标题】:Async/await axios calls with Vue.js 【发布时间】:2018-11-25 02:33:09 【问题描述】:

我在设置其中一个时遇到了一点问题。我的 Vue.js 应用程序中的值。我相信我要么不正确理解异步 axios 调用,要么不理解异步在 Vue.js 中的工作原理。

我有以下三种方法:

updateAvailability(availability) 
    if (availability == true) 
        this.showYourDetails();
     else 
        this.showBookingDetails();
    
,
checkAvailability: async function(event) 
    event.preventDefault();
    const availability = await this.handleAvailabilityRequest(event);
    this.loading = true;
    console.log(availability); //This evaluates to undefined
    const availabilityUpdate = await this.updateAvailability(availability);
    this.loading = false;
,
handleAvailabilityRequest: async function(event) 
    event.preventDefault();
    let valid = this.validateFieldsForAvailabilityRequest(); //Ignore this for this particular question, assume valid is always true

    if (valid)  // This is true
        let config = 
            headers: 
                "X-CSRFToken": this.csrfToken,
                "Content-Type": 'application/x-www-form-urlencoded',
            
        

        let formData = new FormData();
        let reservationTime = this.reservationHourSelected + ':' + this.reservationMinuteSelected;

        formData.set('type', 'availability_request');
        formData.set('session_name', this.sessionName);
        formData.set('reservation_party_size', this.reservationPartySize);
        formData.set('reservation_date', this.reservationDate);
        formData.set('reservation_time', reservationTime);

        await axios.post(' request_absolute_uri ', formData, config).then(function(response) 
            this.availabilityMessage = response.data.message;
        ).catch(function(error) 
            this.availabilityMessage = false;
            console.log(error);
        );
    
    return this.availabilityMessage;

我的 response.data.message 正在从我的框架传回为 True/true,但似乎我没有从 await this.handleAvailabilityRequest() 函数返回任何内容?该帖子肯定会到达服务器,因为日志记录显示了我想要的所有内容 - 然后在 json 响应上下文中返回 message = true。

所以,我猜...帮助!完全傻眼了,为什么这不起作用,除了等待承诺的问题......

【问题讨论】:

你应该在这里使用箭头函数,否则你不会得到正确的上下文。 Vivick 是对的,或者在你的错误回调函数末尾添加.bind(this) 因为您正在更新“this”availabilityMessage,我认为在请求中返回它没有意义。而是在进一步的调用中检查 this.availabilityMessage 而不是可用性。 您还将异步等待与标准承诺混合在一起。这可能会导致我发现的问题。使用其中一种。对于这些情况,我更喜欢 async/await,但我也发现有时我必须在等待的调用上使用 Promise.all。 【参考方案1】:

如果您使用异步等待,为什么要使用 Promise 模式。这消除了回调的使用和 this 绑定丢失

你可以这样做

handleAvailabilityRequest: async function (event) 
  event.preventDefault();
    ...

  try
   let response =  await axios.post(' request_absolute_uri ', formData, config)
      this.availabilityMessage = response.data.message;
  catch(error) 
      this.availabilityMessage = false;
      console.log(error);
    ;
  
  return this.availabilityMessage;

您可以在使用async/await 时使用try/catch 块来处理错误

【讨论】:

“如果你使用异步等待,为什么要使用 Promise”——因为 async 函数返回一个 Promise,而 await 只能等待一个返回 Promise 的函数。 axios 确实返回了一个承诺 @Quentin 我们可以等待该承诺得到解决并返回response "finally" 是尝试捕获后清理的好方法。我一直在用它 恕我直言,这是一个更好的答案。 async/await 改变了游戏规则。避免使用 promises 的那些链式函数肯定会让这个更干净。【参考方案2】:

问题出在这里:

await axios.post(' request_absolute_uri ', formData, config).then(function(response)
  this.availabilityMessage = response.data.message;
).catch(function (error) 
  this.availabilityMessage = false;
  console.log(error);
);

因为您使用的是成熟的function,所以.then 中的this 不会引用实例化对象。请改用箭头函数,以便从外部范围继承 this

await axios.post(' request_absolute_uri ', formData, config)
.then((response) => 
  this.availabilityMessage = response.data.message;
).catch((error) => 
  this.availabilityMessage = false;
  console.log(error);
);

【讨论】:

这就像一个魅力。通过一些修改,外部范围现在正在发生变化。只是出于兴趣,为什么会这样? 对于标准函数,任何函数内部的this 都是该函数的调用上下文 - 使用您的原始代码,即.post 返回的Promise .对于箭头函数,this 总是从外部范围继承,而不是依赖于箭头函数的调用上下文。 如果你必须使用 function() 你总是可以用 bind 绑定父上下文 (this)。 function() .bind(this)

以上是关于使用 Vue.js 进行异步/等待 axios 调用的主要内容,如果未能解决你的问题,请参考以下文章

使用轴和 Vue.js 进行异步/等待调用 - `.then()` 回调未更新 `this.something`

Mock.js + vue.js + axios 结合开发

Mock.js + vue.js + axios 结合开发

Vue基础入门讲义-异步请求axios

使用axios 异步显示数据到页面

Axios-一次发出多个请求(vue.js)