2016-01-23 52 views
1

这就是下面的代码所做的:工作withing一个循环时,JavaScript回调函数

  • 转到表在数据库和检索某些搜索条件,我将发送给谷歌API(PHP文件是getSearchSon .PHP)

  • 有结果后,我想它周围循环,调用谷歌API(searchCriteriasFuc),并将结果保存在一个数组

  • 代码的最后一部分是做一个更新两个不同的表小时从结果谷歌API(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 

}); 
+0

是否发布信息不正确? – Erick

+1

看起来像你应该工作得很好 – adeneo

+0

是否es7异步 - 在这里等待一个选项? –

回答

0

为了获取回调后执行调用谷歌完成,你可以改变:

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的setTimeout的。

考虑使用的承诺和Promise.all让所有清洁得多:d

0

你可以重新在下面不管你getTotalResults功能,它会再搜索,而连续的,但它也应该做的伎俩在与返回的搜索结果一个额外的回调。

'use strict'; 
 

 
function getTotalResults(searchParam, callback) { 
 
    var url = "https://www.googleapis.com/customsearch/v1?q={param}&cx=005894674626506192190:j1zrf-as6vg&key=AIzaSyCanPMUPsyt3mXQd2GOhMZgD4l472jcDNM&dateRestrict=" + (new Date()).getTime(), 
 
    i = 0, 
 
    len = searchParam.length, 
 
    results = [], 
 
    req, nextRequest = function() { 
 
     console.log('received results for "' + searchParam[i] + '"'); 
 
     if (++i < len) { 
 
     completeRequest(url.replace('{param}', searchParam[i]), results, nextRequest); 
 
     } else { 
 
     callback(results); 
 
     } 
 
    }; 
 
    
 
    completeRequest(url.replace('{param}', searchParam[0]), results, nextRequest); 
 
} 
 

 
function completeRequest(url, resultArr, completedCallback) { 
 
    var req = new XMLHttpRequest(); 
 

 
    req.open("GET", url, true); 
 
    req.onreadystatechange = function() { 
 
    if (this.readyState === 4 && this.status == 200) { 
 
     var totalResults = JSON.parse(this.responseText).queries.nextPage[0].totalResults; 
 
     resultArr.push(totalResults); 
 
     completedCallback(); 
 
    } 
 
    }; 
 
    req.send(); 
 
} 
 

 
getTotalResults(['ford', 'volkswagen', 'citroen', 'renault', 'chrysler', 'dacia'], function(searchResults) { 
 
    console.log(searchResults.length + ' results found!', searchResults); 
 
});

不过,既然你已经在你的代码使用JQuery,你也可以建造所有的请求,然后用JQuery.when功能,在这个问题

解释Wait until all jQuery Ajax requests are done?

2

你怎么做的,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)

你可以使用异步/ 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); 
    } 
}); 

UPDATE 2016

不幸的是,async/await提议没能坚持到ES7规范最终,因此它仍然是非标准。

+0

我会尝试实施2016版。我需要包含任何库还是使用JQuery都足够了?我的意思是我从未使用诺言或等待。 – Erick

+0

@Erick老实说,你不能使用ES7开箱即用。几乎没有支持异步/等待的浏览器,但是您可以使用[babel](http://babeljs.io/repl/)将ES7代码转换为ES5,并且必须包含Facebook再生器运行时。 es2015版本可以在所有现代浏览器上正常工作。 –