如何获取Ajax请求结果?请求结束执行代码的正确性咨询
嘿,我明白你的需求啦——你想在Ajax请求完成后执行特定的代码逻辑,但目前的写法存在一个核心问题:Ajax请求是异步操作,所以你直接通过var result = envoyerRequete(...)然后判断if(result)的方式根本得不到预期的结果,因为envoyerRequete返回的是jQuery的Deferred对象(本质是Promise),而不是你在done/fail回调里返回的true或false。
问题出在哪里?
当你调用envoyerRequete时,Ajax请求会在后台异步执行,代码会直接跳过请求过程,继续执行if(result)这一行。此时result是一个Deferred对象,永远会被判定为“真”,导致你的成功/失败逻辑完全失效。而且你在done/fail里返回的true/false也不会改变envoyerRequete的返回值,因为异步回调的返回值无法同步传递给外层代码。
修正方案
下面给你两种常用的正确实现方式:
方案一:使用jQuery Deferred的链式回调(传统写法)
先简化你的请求函数,让它直接返回$.ajax生成的Deferred对象,然后在调用时通过done/fail处理结果:
// 简化后的Ajax请求函数 function envoyerRequete(url, data, type) { return $.ajax({ url: url, dataType: 'json', contentType: 'application/json; charset=UTF-8', data: JSON.stringify(data), type: type }); } // 调用函数,通过链式回调处理成功/失败逻辑 function newAuteur() { var data = { "nom": $("#nomAuteur").val(), "prenom": $("#prenomAuteur").val() }; envoyerRequete('/auteurs/', data, "POST") .done(function (responseData) { console.log('success'); // 这里写请求成功后要执行的代码 // 比如更新页面、提示用户等 }) .fail(function (jqXHR, textStatus, errorThrown) { console.log('fail'); // 这里写请求失败后要执行的代码 // 比如显示错误提示、重置表单等 }); }
这是jQuery处理异步Ajax的标准方式,请求成功时会触发done回调,失败时触发fail回调,你可以在对应的回调里编写特定逻辑。
方案二:使用async/await(更简洁的同步风格写法)
如果你的运行环境支持ES6+,可以用async/await让异步代码看起来像同步代码,逻辑更清晰:
// 请求函数保持不变,jQuery的Deferred兼容Promise规范 function envoyerRequete(url, data, type) { return $.ajax({ url: url, dataType: 'json', contentType: 'application/json; charset=UTF-8', data: JSON.stringify(data), type: type }); } // 将调用函数标记为async函数 async function newAuteur() { var data = { "nom": $("#nomAuteur").val(), "prenom": $("#prenomAuteur").val() }; try { // await会等待Ajax请求完成,成功后进入这里 const responseData = await envoyerRequete('/auteurs/', data, "POST"); console.log('success'); // 成功后的代码写在这里 } catch (error) { // 请求失败时会进入catch块 console.log('fail', error); // 失败后的代码写在这里 } }
await关键字会暂停函数执行,直到Ajax请求完成,成功则返回响应数据,失败则抛出错误,通过try/catch可以优雅地处理两种情况。
总结
异步操作的核心就是不能试图同步获取结果,必须通过回调、Promise链式调用或者async/await来处理操作完成后的逻辑。上面两种方案都能满足你“在Ajax请求结束后执行特定代码”的需求,你可以根据自己的代码风格和环境选择合适的方式。
内容的提问来源于stack exchange,提问作者Royce

