如何在JavaScript循环中调用与Ajax相关的函数?

时间:2019-04-02 05:37:33

标签: javascript jquery

我正在运行一个循环,并且在循环内我正在调用一个函数。该函数进行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>';
 }

3 个答案:

答案 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;
}