React中使用async/await确保getUsersProduct执行完成后再执行后续代码
异步函数执行顺序问题解决方案
问题背景
现有React代码片段如下:
function login(event) { event.preventDefault(); console.log("*1*"); let formData = new FormData(event.target); ApiRequest.axiosInstance({ method: "post", url: "/login/login.php", data: formData, headers: {} }) .then(res => { console.log("*2*"); getUsersProduct; console.log("*3*"); }) .catch((err) => { console.error(err); console.log("*4*"); }) .then(() => { console.log("Login Finished"); console.log("*5*"); }); } function getUsersProduct() { console.log("*6*"); ApiRequest.axiosInstance({ method: "post", url: "/login/getUsersProduct.php", data: formData, headers: { "Content-Type": "multipart/form-data" } }) .then(res => .... console.log("*7*"); }
当前控制台输出顺序为 *1* *2* *6* *3*,期望实现顺序为 *1* *2* *6* *7* *3*,即需确保getUsersProduct函数完全执行完成(包括内部异步请求处理及*7*输出)后,再执行后续的console.log("*3*")代码。
解决方案
核心思路是让getUsersProduct返回异步操作的Promise,并在调用时等待其执行完成,async/await是更简洁的实现方式,也可以用Promise链式调用,具体如下:
1. 修正getUsersProduct函数
首先让函数返回axios请求的Promise,同时修复内部formData未定义的问题(需通过参数传入):
function getUsersProduct(formData) { console.log("*6*"); // 返回axios请求的Promise,确保异步操作能被等待 return ApiRequest.axiosInstance({ method: "post", url: "/login/getUsersProduct.php", data: formData, headers: { "Content-Type": "multipart/form-data" } }) .then(res => { // 这里添加res的业务处理逻辑 console.log("*7*"); }); }
2. 在login函数中等待异步操作完成
方式一:使用async/await(推荐,代码可读性更高)
将then的回调函数标记为async,通过await等待getUsersProduct执行完成:
function login(event) { event.preventDefault(); console.log("*1*"); let formData = new FormData(event.target); ApiRequest.axiosInstance({ method: "post", url: "/login/login.php", data: formData, headers: {} }) .then(async res => { console.log("*2*"); // 等待getUsersProduct的异步操作全部完成 await getUsersProduct(formData); console.log("*3*"); }) .catch((err) => { console.error(err); console.log("*4*"); }) .then(() => { console.log("Login Finished"); console.log("*5*"); }); }
方式二:使用Promise链式调用
若不想用async/await,可以通过嵌套then实现等待:
function login(event) { event.preventDefault(); console.log("*1*"); let formData = new FormData(event.target); ApiRequest.axiosInstance({ method: "post", url: "/login/login.php", data: formData, headers: {} }) .then(res => { console.log("*2*"); // 链式调用getUsersProduct的Promise,完成后再执行*3* return getUsersProduct(formData).then(() => { console.log("*3*"); }); }) .catch((err) => { console.error(err); console.log("*4*"); }) .then(() => { console.log("Login Finished"); console.log("*5*"); }); }
原代码问题分析
原代码中仅写了getUsersProduct;(未调用函数),即使修改为getUsersProduct(),由于内部axios请求是异步操作,函数会先同步执行console.log("*6*")后立即返回,此时then回调会继续执行console.log("*3*"),而axios请求完成后才会输出*7*,导致顺序不符合预期。只有让getUsersProduct返回Promise并等待其完成,才能保证*7*在*3*之前输出。
内容的提问来源于stack exchange,提问作者hansvdzz
相关产品推荐
相关产品推荐

