我正在运行一个循环,并且在循环内我正在调用一个函数。该函数进行ajax调用并返回响应,但问题是循环没有等待响应,因此该函数返回undefined。
function checkBidStatus(index) {
$.ajax({
type:'get',
url:'/orderbook/checkorderdetails',
success: function(data){
$parsedData = JSON.parse(data);
if($parsedData[index]) {
return "Hello";
} else {
return "Bye";
}
//$("#bid-details .modal-dialog").html(data);
},
error: function (response) {
console.log(response);
}
});
}
let content = '';
for(let i = 1; i <= 10; i++ ) {
content += '<div>' +
(checkBidStatus(i)) +
'</div>';
}
答案 0 :(得分:2)
问题在于for循环是同步的,但是ajax调用是异步的。即,该功能必须等待服务器响应。因此,在迭代到下一个请求之前,调用方需要使用回调或Promise。
有使用某些库(例如异步程序)完成此任务的绝妙方法,但是使用Promise解决此任务的“快速vanillaJS”方法如下所示:
const contentTemplate = '<div>[BID_RESULT]</div>';
const nRequests = 10;
var requestCnt = 0;
var content = '';
function checkBidStatus(index) {
return new Promise((resolve, reject) => {
$.ajax({
type:'get',
url:'/orderbook/checkorderdetails',
success: function(data){
$parsedData = JSON.parse(data);
resolve({ index: index + 1, msg: $parsedData ? "Hello" : "Bye" });
},
error: reject
});
// <-- NOTE: there is no return statement at this line. Hence if
// you were to call this function from your for loop, you'd see
// undefined
}
}
然后,您可以继续递归调用该函数:
function multipleRequests(){
checkBidStatus(requestCnt)
.then((resp) => { // This runs if the promise RESOLVES (i.e., success)
content = contentTemplate.replace('[BID_RESULT]', resp.msg);
// --- [then do what you want with content] --- //
// Request again
requestCnt++;
if( requestCnt < nRequests ){
multipleRequests();
}
})
.catch(console.error) // This runs if promise rejects (i.e., has an error)
}
// Run:
multipleRequests();
答案 1 :(得分:1)
为什么不在内部使用Promise并等待该诺言以获得所需的结果,然后再更新DOM?在您的checkBidStatus方法中,您可以创建一个承诺并将其返回。当ajax结果可用时,用ajax结果解决诺言。
方法的调用者需要等待promise解析,然后更新DOM。
let content = '';
for(let i = 1; i <= 10; i++ ) {
checkBidStatus(i).then(result => {
content += '<div>' +result + '</div>';
})
}
注意:我还没有测试代码,但是类似的东西应该可以工作。同样,不能保证基于索引创建的div的顺序,因此,如果顺序很重要,则可能需要注意这一点。
答案 2 :(得分:0)
对于循环中的每个迭代,您都应等待服务器的响应。
function checkBidStatus(index) {
$.ajax({
type: 'get',
url: '/orderbook/checkorderdetails',
success: function(data) {
$parsedData = JSON.parse(data);
if ($parsedData[index]) {
return {
msg: 'Hello',
index: index + 1,
};
} else {
return {
msg: 'Bye',
index: index + 1,
};
}
//$("#bid-details .modal-dialog").html(data);
},
error: function(response) {
console.log(response);
},
});
}
let content = '';
let i = 1;
while (i <= 10) {
let { msg, index } = checkBidStatus(i);
content += '<div>' + msg + '</div>';
i = index;
}