如何从包含多个AJAX请求的函数中返回正确值?
解决嵌套AJAX请求无法返回结果的问题
你猜的没错,问题核心就是AJAX是异步操作——patato函数会先执行完所有同步代码(包括最后的console.log("Çalıştı 3")),然后才会在未来某个时间点触发AJAX的success回调。你在第二个回调里的return true,只是回调函数自身的返回值,和patato函数的返回值完全无关,所以patatos最终是undefined,会打印"Patato false"。
方案一:使用Promise + async/await封装
重写patato函数,让它返回一个Promise对象,通过resolve传递最终结果:
var patato = function(){ return new Promise((resolve, reject) => { $.ajax({ type: 'POST', url: 'https://jsonplaceholder.typicode.com/posts', dataType: 'json', data: { title: 'foo', body: 'bar', userId: 1, }, success:function(res){ console.log("Work 1") $.ajax({ type: 'POST', url: 'https://jsonplaceholder.typicode.com/posts', dataType: 'json', data: { title: 'foo', body: 'bar', userId: 1, }, success:function(res){ console.log("Work 2") resolve(true); // 传递最终结果 }, error: function(err) { reject(err); // 捕获第二个请求的错误 } }) }, error: function(err) { reject(err); // 捕获第一个请求的错误 } }) }) }
调用时使用async/await等待异步操作完成:
async function runPatato() { try { var patatos = await patato(); if(patatos) { console.log("Patato true") }else{ console.log("Patato false") } } catch(err) { console.error("请求出错:", err); } } runPatato();
方案二:利用jQuery Deferred链式调用
jQuery的$.ajax本身返回Deferred对象,可以通过then方法串联异步操作:
var patato = function(){ return $.ajax({ type: 'POST', url: 'https://jsonplaceholder.typicode.com/posts', dataType: 'json', data: { title: 'foo', body: 'bar', userId: 1, } }).then(function(res){ console.log("Work 1") // 返回第二个AJAX的Deferred对象,继续串联 return $.ajax({ type: 'POST', url: 'https://jsonplaceholder.typicode.com/posts', dataType: 'json', data: { title: 'foo', body: 'bar', userId: 1, } }).then(function(res){ console.log("Work 2") return true; // 传递最终结果 }); }); } // 通过then接收最终结果 patato().then(function(patatos){ if(patatos) { console.log("Patato true") }else{ console.log("Patato false") } }).catch(function(err){ console.error("请求出错:", err); });
执行顺序说明
修改前的代码执行顺序:
- 调用
patato() - 发送第一个AJAX请求(异步)
- 执行
console.log("Çalıştı 3") patato函数返回undefined- 打印"Patato false"
- 第一个AJAX请求成功,打印"Work 1"
- 发送第二个AJAX请求(异步)
- 第二个AJAX请求成功,打印"Work 2"并
return true(无实际作用)
修改后的执行顺序:
- 调用
patato(),触发第一个AJAX请求 - 第一个AJAX请求成功,打印"Work 1"并触发第二个AJAX请求
- 第二个AJAX请求成功,打印"Work 2"并传递结果
true - 接收结果,打印"Patato true"
内容的提问来源于stack exchange,提问作者Alper Uluses
相关产品推荐
相关产品推荐

