处理循环时的JavaScript回调函数

处理循环时的JavaScript回调函数,javascript,Javascript,下面的代码就是这样做的: 转到数据库中的一个表并检索一些搜索条件,我将发送到GoogleAPI(PHP文件为getSearchSon.PHP) 在得到结果之后,我想循环一下,调用googleapi(searchCriteriasFuc)并将结果存储在一个数组中 代码的最后一部分是使用从GoogleAPI(updateSearchDb.php)返回的结果对两个不同的表进行更新 在我的代码中,有几次我不喜欢使用setTimeout。我不想使用setTimeout,而是想以更有效的方式正确使用回调

下面的代码就是这样做的:

  • 转到数据库中的一个表并检索一些搜索条件,我将发送到GoogleAPI(PHP文件为getSearchSon.PHP)

  • 在得到结果之后,我想循环一下,调用googleapi(searchCriteriasFuc)并将结果存储在一个数组中

  • 代码的最后一部分是使用从GoogleAPI(updateSearchDb.php)返回的结果对两个不同的表进行更新

在我的代码中,有几次我不喜欢使用setTimeout。我不想使用setTimeout,而是想以更有效的方式正确使用回调函数(这可能是我的问题的原因)。我这样做的最佳方式是什么

$(document).ready(function() {


    $.ajax({ 

        url: 'getSearchSon.php',  

        type: 'POST',

        async: true,

        dataType: 'Text',

        /*data: { }, */

        error: function(a, b, c) { alert(a+b+c); }  

    }).done(function(data) {


    if(data != "connection")
    {
        var dataSent = data.split("|");

        var search_criterias = JSON.parse(dataSent[0]);

        var date_length = dataSent[1];

        var divison_factor = dataSent[2];

        var length = search_criterias.length;

        var arrXhr = [];

        var totalResultsArr = [];

        var helperFunc = function(arrayIndex)
        {
            return function()
            {
                var totalResults = 0;

                if (arrXhr[arrayIndex].readyState === 4 && arrXhr[arrayIndex].status == 200) 
                {
                    totalResults = JSON.parse(arrXhr[arrayIndex].responseText).queries.nextPage[0].totalResults;

                    totalResultsArr.push(totalResults);
                }
            }
        }

        var searchCriteriasFuc = function getTotalResults(searchParam, callback) 
        {   
            var searchParamLength = searchParam.length;

            var url = "";

            for(var i=0;i<searchParamLength;i++)
            {
                url = "https://www.googleapis.com/customsearch/v1?q=" + searchParam[i] + "&cx=005894674626506192190:j1zrf-as6vg&key=AIzaSyCanPMUPsyt3mXQd2GOhMZgD4l472jcDNM&dateRestrict=" + date_length;

                arrXhr[i] = new XMLHttpRequest();

                arrXhr[i].open("GET", url, true);

                arrXhr[i].send();

                arrXhr[i].onreadystatechange = helperFunc(i);
            }

            setTimeout(function()
            {       
                if (typeof callback == "function")  callback.apply(totalResultsArr);
            }, 4000);


            return searchParam;
        }   

        function callbackFunction()
        { 
            var results_arr = this.sort();

            var countResultsArr = JSON.stringify(results_arr);

            $.ajax({

                url: 'updateSearchDb.php',  

                type: 'POST',

                async: true,

                dataType: 'Text',

                data: { 'countResultsArr': countResultsArr },

                error: function(a, b, c) { alert(a+b+c); }  

            }).done(function(data) {

                var resultsDiv = document.getElementById("search");

                if(data == "NORECORD") resultsDiv.innerHTML = 'Updated failed. There was a problem with the database';

                else resultsDiv.innerHTML = 'Update was successful';

            }); //end second ajax call
        }

        //llamando funcion principal
        var arrSearchCriterias = searchCriteriasFuc(search_criterias, callbackFunction);

    }
    else
    {
        alert("Problem with MySQL connection.");
    }

    }); // end ajax 

});
$(文档).ready(函数(){
$.ajax({
url:'getSearchSon.php',
键入:“POST”,
async:true,
数据类型:“文本”,
/*数据:{}*/
错误:函数(a,b,c){alert(a+b+c);}
}).完成(功能(数据){
如果(数据!=“连接”)
{
var dataSent=data.split(“|”);
var search_criterias=JSON.parse(dataSent[0]);
var date_length=dataSent[1];
var division_factor=dataSent[2];
变量长度=搜索标准长度;
var arrXhr=[];
var totalResultsArr=[];
var helperFunc=函数(arrayIndex)
{
返回函数()
{
var totalResults=0;
if(arrXhr[arrayIndex].readyState==4&&arrXhr[arrayIndex].status==200)
{
totalResults=JSON.parse(arrXhr[arrayIndex].responseText).querys.nextPage[0].totalResults;
totalResultsArr.push(totalResults);
}
}
}
var searchCriteriasFuc=函数getTotalResults(searchParam,回调)
{   
var searchParamLength=searchParam.length;
var url=“”;

对于(var i=0;i要在google调用完成后执行回调,您可以更改:

    var requestCounter = 0;        

    var helperFunc = function(arrayIndex)
    {
        return function()
        {
            if (arrXhr[arrayIndex].readyState === 4 && arrXhr[arrayIndex].status == 200) 
            {
                requestCounter++;                    

                totalResults = JSON.parse(arrXhr[arrayIndex].responseText).queries.nextPage[0].totalResults;

                totalResultsArr.push(totalResults);

                if (requestCounter === search_criterias.length) {
                    callbackFunction.apply(totalResultsArr);
                }
            }
        }
    }
然后删除searchCreteriaFuc上的设置超时


考虑使用Promissions并使所有内容更清晰:D

您可以在以下事项中重新格式化getTotalResults函数,它将按顺序进行搜索,但它还应该通过额外的回调返回结果

“严格使用”;
函数getTotalResults(searchParam,回调){
变量url=”https://www.googleapis.com/customsearch/v1?q={param}&cx=005894674626506192190:j1zrf-as6vg&key=aizasycanpmupsyty3mxqd2gohmzgd472jcdnm&dateRestrict=“+(新日期()).getTime(),
i=0,
len=searchParam.length,
结果=[],
req,nextRequest=函数(){
log('接收到“'+searchParam[i]+'”的结果);
如果(++i
2015年你是怎么做到的 回调是过去的事情。现在,您使用
Promise
s表示异步任务的结果值。下面是一些未经测试的代码:

$(document).ready(function() {
  $.ajax({ 
      url: 'getSearchSon.php',  
      type: 'POST',
      async: true,
      dataType: 'text'
      /*data: { }, */
  }).then(function(data) {
    if (data == 'connection') {
      alert("Problem with MySQL connection.");
    } else {
      var dataSent = data.split("|");
      var search_criterias = JSON.parse(dataSent[0]);
      var date_length = dataSent[1];
      var divison_factor = dataSent[2];

      return Promise.all(search_criterias.map(function(criteria) {
        return $.ajax({
          url: "https://www.googleapis.com/customsearch/v1"
            + "?q=" + criteria 
            + "&cx=005894674626506192190:j1zrf-as6vg"
            + "&key=AIzaSyCanPMUPsyt3mXQd2GOhMZgD4l472jcDNM"
            + "&dateRestrict=" + date_length,
          type: 'GET'
        });
      })).then(function(totalResultsArr) {
        totalResultsArr.sort();
        var countResultsArr = JSON.stringify(totalResultsArr);

        return $.ajax({
          url: 'updateSearchDb.php',  
          type: 'POST',
          async: true,
          dataType: 'text',
          data: { 'countResultsArr': countResultsArr },
          error: function(a, b, c) { alert(a+b+c); }  
        });
      }).then(function(data) {
        var resultsDiv = document.getElementById("search");
        if(data == "NORECORD") {
          resultsDiv.innerHTML = 'Updated failed. There was a problem with the database';
        } else {
          resultsDiv.innerHTML = 'Update was successful';
        }
      });
    }
  }).then(null, function() {
    alert('Some unexpected error occured: ' + e);
  });
});
这就是您在2016年的工作方式(ES7) 您可以使用async/await

$(document).ready(async() => {
  try {
    var data = await $.ajax({ 
        url: 'getSearchSon.php',  
        type: 'POST',
        async: true,
        dataType: 'text'
        /*data: { }, */
    });
    if (data == 'connection') {
      alert("Problem with MySQL connection.");
    } else {
      var dataSent = data.split("|");
      var search_criterias = JSON.parse(dataSent[0]);
      var date_length = dataSent[1];
      var divison_factor = dataSent[2];

      var totalResultsArr = await Promise.all(
        search_criterias.map(criteria => $.ajax({
          url: "https://www.googleapis.com/customsearch/v1"
          + "?q=" + criteria 
          + "&cx=005894674626506192190:j1zrf-as6vg"
          + "&key=AIzaSyCanPMUPsyt3mXQd2GOhMZgD4l472jcDNM"
          + "&dateRestrict=" + date_length,
          type: 'GET'
        }))
      );

      totalResultsArr.sort();
      var countResultsArr = JSON.stringify(totalResultsArr);
      var data2 = await $.ajax({
          url: 'updateSearchDb.php',  
          type: 'POST',
          async: true,
          dataType: 'text',
          data: { 'countResultsArr': countResultsArr },
          error: function(a, b, c) { alert(a+b+c); }  
      });
      if(data2 == "NORECORD") {
        resultsDiv.innerHTML = 'Updated failed. There was a problem with the database';
      } else {
        resultsDiv.innerHTML = 'Update was successful';
      }
    }
  } catch(e) {
    alert('Some unexpected error occured: ' + e);
  }
});
2016年更新


不幸的是,
async/await
提案最终没有符合ES7规范,因此它仍然是非标准的。

发布的答案是否不正确?看起来您得到的应该是正确的ES7 async wait选项在这里吗?如果我理解正确,您希望按顺序执行http请求,而不是所有的请求m立刻,对吗?不相关,但是totalResults是一个全局变量吗?我将尝试实现2016版本。我需要包括任何库还是使用JQuery就足够了吗?我的意思是我从来没有使用过Promise或await。@埃里克说实话,你还不能直接使用ES7。几乎没有任何浏览器支持async/await,但你可以使用将ES7代码传输到ES5,并且必须包括Facebooks regenerator runtime。es2015版本应该可以在所有现代浏览器上正常工作。