Axios POST请求同时触发then与catch分支问题求助
问题:POST请求返回200却同时触发axios的then与catch分支
我编写了保存文章的submit函数,浏览器返回状态码200且文章已成功保存,但该POST请求同时触发了axios的then成功分支与catch错误分支,日志中同时出现console.log(1)和console.log(3)的输出,无法理解原因。
浏览器日志
[Log] 1 (src_vue_component_role_common_article_add_vue-f9ecfd1edc9c94aaed1b.js, line 243) [Log] 3 (src_vue_component_role_common_article_add_vue-f9ecfd1edc9c94aaed1b.js, line 259) [Error] LOG – "There was an error: " – "" Error (src_vue_component_role_common_article_articles-editor_vue-f9ecfd1edc9c94aaed1b.js:1560) (anonymous function) (src_vue_component_role_common_article_add_vue-f9ecfd1edc9c94aaed1b.js:260)
submit函数代码
submit() { if (this.validate()) { let formData = this.$refs["media-manager-" + this.uid] ? this.$refs["media-manager-" + this.uid].getFormData() : new FormData(); formData.append("article", JSON.stringify(this.article)); this.loading = true; let context = this; this.progress = 0; axios .post(this.articlePath, formData, { headers: { "Content-Type": "multipart/form-data" }, onUploadProgress: function (progressEvent) { context.progress = Math.round( (progressEvent.loaded * 100) / progressEvent.total ); }, }) .then((response) => { const data = response.data; if (data.success) { console.log(1); toastr.success("article saved", null, { positionClass: Storage.preferences.nPos, }); const article = JSON.parse(data.article); this.$emit("saved", article); this.loading = false; document.getElementById("contentPad").scrollIntoView(); this.progress = 0; } else { console.log(2); Error(response); this.loading = false; this.progress = 0; } }) .catch((response) => { console.log(3); Error(response); this.loading = false; this.progress = 0; }); } },
原因分析
这种情况是then分支的执行过程中抛出了未被捕获的错误,导致Promise链从then分支跳转到catch分支执行,所以两个分支的日志都会出现。
从错误栈可以看到,错误来自articles-editor组件的1560行,说明错误并非直接来自submit函数的then分支代码,而是以下几种情况之一:
- then分支中调用的方法(如
toastr.success、JSON.parse)抛出了错误 this.$emit("saved", article)触发的监听回调中抛出了错误(父组件或其他组件处理saved事件时出错)- 访问
Storage.preferences.nPos时,Storage.preferences未定义或nPos不存在,导致取值错误 document.getElementById("contentPad")未找到元素,调用scrollIntoView()抛出错误
另外注意:else分支中的Error(response)只是创建了Error对象,并没有抛出,不会触发catch分支,若要触发需要改为throw new Error(JSON.stringify(response))。
解决步骤
- 在then分支内部添加try-catch捕获错误,定位具体出错点:
.then((response) => { try { const data = response.data; if (data.success) { console.log(1); toastr.success("article saved", null, { positionClass: Storage.preferences?.nPos || 'toast-bottom-right', // 用可选链避免取值错误,添加默认值 }); const article = JSON.parse(data.article); this.$emit("saved", article); this.loading = false; const contentPad = document.getElementById("contentPad"); if (contentPad) contentPad.scrollIntoView(); // 先判断元素是否存在再调用方法 this.progress = 0; } else { console.log(2); throw new Error('保存失败:' + JSON.stringify(response)); this.loading = false; this.progress = 0; } } catch (e) { console.error('Then分支执行错误:', e); throw e; // 若需要进入catch分支则抛出,否则可自行处理 } })
- 检查
articles-editor组件1560行的代码,排查未处理的错误逻辑 - 逐个验证then分支中可能出错的点:确认
data.article是合法JSON、Storage.preferences已定义、contentPad元素存在、saved事件的监听回调无错误
内容的提问来源于stack exchange,提问作者Sam
相关产品推荐
相关产品推荐

