And*_*unn 7 javascript promise vue.js axios es6-modules
我目前正在开展一个项目,为 Udemy 讲师 API 创建客户端。
\n\n我已经用 Vue 编写了客户端,使用 Axios 作为我的 HTTP 客户端。
\n\n我将不同的 API 请求抽象为 ES6 化的 API 包装库 ( Udemy.js) 中的函数,以便可以轻松地重用它们。
Udemy.js首先初始化 Axios 的实例,然后按照 Promise 导出使用该实例作为基础的 API 函数。
下面摘自该文件,但为了便于阅读,我已经删除了模块导出的除其中一个函数之外的所有函数(并且显然编辑了 API 令牌)。端点 URI 包含“message-threadsssss”\xe2\x80\x94,这是故意的,以导致服务器返回 404:
\n\nimport axios from \'axios\';\r\n\r\nconst token = \'***************************\';\r\nconst axiosOptions = {\r\n baseURL: \'https://www.udemy.com/instructor-api/v1\',\r\n timeout: 10000,\r\n headers: {\r\n Accept: \'*/*\',\r\n \'Content-Type\': \'application/json;charset=utf-8\',\r\n Authorization: `Bearer ${token}`,\r\n },\r\n};\r\n\r\nconst axiosInstance = axios.create(axiosOptions);\r\n\r\nexport default {\r\n postMessage(messageThreadId, messageBody) {\r\n return axiosInstance\r\n .post(`/message-threadssss/${messageThreadId}/messages/`, {\r\n content: messageBody,\r\n })\r\n .then(response => response.data)\r\n .catch(error => error);\r\n },\r\n}Run Code Online (Sandbox Code Playgroud)\r\nUdemyApi.postMessage(threadId, threadReply);\r\n.then((response) => {\r\n this.isLoading = false;\r\n this.sentReply = response;\r\n this.replyBody = \'\';\r\n this.$root.$emit(\'reply-sent\', {\r\n threadId: this.thread.id,\r\n sentReply: this.sentReply,\r\n });\r\n })\r\n .catch((error) => {\r\n if (error.response) {\r\n // Case 1 (Server returned error)\r\n console.log(error.response.data);\r\n console.log(error.response.status);\r\n console.log(error.response.headers);\r\n } else if (error.request) {\r\n // Case 2 (Pre-response error)\r\n console.log(error.request);\r\n } else {\r\n // Case 3 (Mysterious error)\r\n console.log(\'Error:\', error.message);\r\n }\r\n this.$root.$emit(\'show-snackbar\', {\r\n message: `Failed to send. ${error} `,\r\n actionText: \'Understood. :(\',\r\n });\r\n this.isLoading = false;\r\n });Run Code Online (Sandbox Code Playgroud)\r\n请求发送没有问题,如果请求成功(即 2xx),Vue 组件就能够访问块中的响应数据then()。
当服务器返回错误(在本例中为 404)时,我希望捕获的错误包含一个response对象(情况 1)。
相反,没有response对象返回并出现错误(情况 2),这使我无法正确处理它。当请求确实导致服务器响应 404 错误时,就会发生这种情况:
HTTP/2.0 404 Not Found\ncontent-type: text/json\nRun Code Online (Sandbox Code Playgroud)\n\n我读过,如果 Axios 应用了拦截器,可能会导致此问题,但在这种情况下,我没有应用任何拦截器。
\n\n总而言之,我有点不知所措。如何将服务器的响应获取到我的 Vue 组件中?
\n\n编辑(2月6日)
\n\n我没有在最初的帖子中包含所有有用的控制台输出,所以就在这里。执行的 console.log() 行是案例 2 行(仅添加一个控制台日志条目,而不是像案例 3 那样以“Error:”为前缀):
\n\n12:22:28.748\nXMLHttpRequest\n mozAnon: false\n mozSystem: false\n onabort: null\n onerror: function handleError()\n onload: null\n onloadend: null\n onloadstart: null\n onprogress: null\n onreadystatechange: function handleLoad()\n ontimeout: function handleTimeout()\n readyState: 4\n response: ""\n responseText: ""\n responseType: ""\n responseURL: ""\n responseXML: null\n status: 0\n statusText: ""\n timeout: 100000\n upload: XMLHttpRequestUpload { onloadstart: null, onprogress: null, onabort: null, \xe2\x80\xa6 }\n withCredentials: false\n <prototype>: XMLHttpRequestPrototype { open: open(), setRequestHeader: setRequestHeader(), send: send(), \xe2\x80\xa6 }\nreplybox.vue:72\nRun Code Online (Sandbox Code Playgroud)\n\n编辑2(2月6日)
\n\n如果我从定义中删除then()and ,看起来像这样:catch()postMessage()
postMessage(messageThreadId, messageBody) {\n return axiosInstance\n .post(`/message-threadssss/${messageThreadId}/messages/`, {\n content: messageBody,\n });\n },\nRun Code Online (Sandbox Code Playgroud)\n\n然后简化catch()调用块postMessage()以仅输出error对象,如下所示:
.catch((error) => {\n console.log(error);\n this.$root.$emit(\'show-snackbar\', {\n message: `Failed to send. ${error} `,\n actionText: \'Understood. :(\',\n });\n this.isLoading = false;\n });\nRun Code Online (Sandbox Code Playgroud)\n\n控制台输出:
\n\n12:38:51.888 Error: "Network Error"\n createError webpack-internal:///./node_modules/axios/lib/core/createError.js:16:15\n handleError webpack-internal:///./node_modules/axios/lib/adapters/xhr.js:87:14\nreplybox.vue:62\nRun Code Online (Sandbox Code Playgroud)\n\n编辑 3(1 月 6 日)
\n\n我意识到在之前的编辑中,我在定义中省略了error.requestafter I\d.then和 的输出。如果我重新添加到组件中的调用块,则输出如下:.catchpostMessageconsole.log(error.request);.catch
12:58:55.436\nXMLHttpRequest\n mozAnon: false\n mozSystem: false\n onabort: null\n onerror: function handleError()\n onload: null\n onloadend: null\n onloadstart: null\n onprogress: null\n onreadystatechange: function handleLoad()\n ontimeout: function handleTimeout()\n readyState: 4\n response: ""\n responseText: ""\n responseType: ""\n responseURL: ""\n responseXML: null\n status: 0\n statusText: ""\n timeout: 100000\n upload: XMLHttpRequestUpload { onloadstart: null, onprogress: null, onabort: null, \xe2\x80\xa6 }\n withCredentials: false\n <prototype>: XMLHttpRequestPrototype { open: open(), setRequestHeader: setRequestHeader(), send: send(), \xe2\x80\xa6 }\nRun Code Online (Sandbox Code Playgroud)\n\n编辑4(2月6日)
\n\n为了确认或排除 API 抽象层的实现,我直接在组件中调用了 Axios 实例:
\n\nconst token = \'*********************\';\nconst axiosOptions = {\n baseURL: \'https://www.udemy.com/instructor-api/v1\',\n timeout: 100000,\n headers: {\n Accept: \'*/*\',\n \'Content-Type\': \'application/json;charset=utf-8\',\n Authorization: `Bearer ${token}`,\n },\n};\nconst axiosInstance = axios.create(axiosOptions);\naxiosInstance\n.post(`/message-threadssss/${this.thread.id}/messages/`, {\n content: this.replyBody,\n})\n.then((response) => {\n this.isLoading = false;\n this.sentReply = response;\n this.replyBody = \'\';\n this.$root.$emit(\'reply-sent\', {\n threadId: this.thread.id,\n sentReply: this.sentReply,\n });\n})\n.catch((error) => {\n console.log(\'Error obj: \', error);\n console.log(\'Request error obj: \', error.request);\n this.$root.$emit(\'show-snackbar\', {\n message: `Failed to send. ${error} `,\n actionText: \'Understood. :(\',\n });\n this.isLoading = false;\n this.axiosResult = error;\n});\nRun Code Online (Sandbox Code Playgroud)\n\n和以前一样,服务器返回了预期的 404,并且.catch我的组件中的块捕获了错误。
但和以前一样,捕获的错误缺少响应
\n\n13:25:45.783 Error obj: Error: "Network Error"\n createError webpack-internal:///./node_modules/axios/lib/core/createError.js:16:15\n handleError webpack-internal:///./node_modules/axios/lib/adapters/xhr.js:87:14\nreplybox.vue:79\n\n13:25:45.786 Request error obj: \nXMLHttpRequest\n mozAnon: false\n mozSystem: false\n onabort: null\n onerror: function handleError()\n onload: null\n onloadend: null\n onloadstart: null\n onprogress: null\n onreadystatechange: function handleLoad()\n ontimeout: function handleTimeout()\n readyState: 4\n response: ""\n responseText: ""\n responseType: ""\n responseURL: ""\n responseXML: null\n status: 0\n statusText: ""\n timeout: 100000\n upload: XMLHttpRequestUpload { onloadstart: null, onprogress: null, onabort: null, \xe2\x80\xa6 }\n withCredentials: false\n <prototype>: XMLHttpRequestPrototype { open: open(), setRequestHeader: setRequestHeader(), send: send(), \xe2\x80\xa6 }\nreplybox.vue:80\nRun Code Online (Sandbox Code Playgroud)\n