Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何确保包含多个$.ajax调用的函数完全同步运行,并允许在执行时重新绘制浏览器_Javascript_Jquery_Ajax_Settimeout - Fatal编程技术网

Javascript 如何确保包含多个$.ajax调用的函数完全同步运行,并允许在执行时重新绘制浏览器

Javascript 如何确保包含多个$.ajax调用的函数完全同步运行,并允许在执行时重新绘制浏览器,javascript,jquery,ajax,settimeout,Javascript,Jquery,Ajax,Settimeout,我一直致力于将函数写入: 1) 使用$.ajax调用处理输入数组以填充输出数组(下面是inputList) 2) 以下是我所拥有的,但我有一些问题: 当我调用requestData()时,它直接运行到处理outputList数组,而没有完全填充/填充它-它将一个值放入其中,然后开始处理该值,但该函数显然仍然以异步方式单独运行到后续处理。我需要它是完全同步的,这样它在inputList数组被完全处理之前不会返回 我没有看到浏览器在每次调用runajax()函数时都会重新绘制其html更新的div

我一直致力于将函数写入:

1) 使用$.ajax调用处理输入数组以填充输出数组(下面是inputList)

2) 以下是我所拥有的,但我有一些问题:

  • 当我调用requestData()时,它直接运行到处理outputList数组,而没有完全填充/填充它-它将一个值放入其中,然后开始处理该值,但该函数显然仍然以异步方式单独运行到后续处理。我需要它是完全同步的,这样它在inputList数组被完全处理之前不会返回

  • 我没有看到浏览器在每次调用runajax()函数时都会重新绘制其html更新的div,我正在尝试使用setTimeout来完成这项工作

3) 我已经将ajax请求设置为同步(async:false)——但这似乎没有帮助

我曾尝试使用jQuery的$。何时提供确保按顺序调用所有内容的功能,但显然我没有正确地这样做

如果您能提供帮助,我将不胜感激。我之前已经就此提出了相关问题,并获得了一些有用的帮助。但我仍然没有解决这个问题

谢谢

//declare holding function requestData - expects a non-empty input data array named inputList
    function requestData() {

//declare inner function runajax
        function runajax() {

            if(inputList.length > 0) {
//get first item from inputlist and shorten inputList
                var data = $.trim(inputList.shift());

                function getData() {
//send the data to server
                    return $.ajax({
                        url: 'sada_ajax_fetch_data.php',
                        cache: false,
                        async: false,
                        method: "post",
                        timeout: 2000,
                        data: {
                            requesttype: "getmydata",
                            email: encodeURIComponent(data)
                         }
                    });
                }

                function handleReturnedData (response) {
                    response = $.trim(decodeURIComponent(response));
//update the div inner html
                    if(response == "Failed") {
                        $('#fetchupdatestatus').html('There was an error retrieving the data you requested!'); 
                    } else {
                        $('#fetchupdatestatus').html('The item returned was '+response);                    
                    }

//add the response from ajax to the end of the outputList array
                    outputList.push(response);
//set up the next ajax call
                    var doNextBitOfWork = function () {
                        runajax();
                    };
//call setTimeout so that browser shows refreshed div html
                    setTimeout(doNextBitOfWork, 0);
//return
                    return $.when();
                }

//do the next ajax request and response processing
                return getData().done(handleReturnedData);

            } else {
//did the last one so return
                return $.when();
            }
        }
//kick off the ajax calls
        runajax();
    }

    var inputList = new Array();
    var outputList = new Array();

    .....load +/- 100 values to be processed using ajax into array inputList

    requestData();

    .....process stuff in array outputList
    .....etc
之前我的回答是“你做错了”,但后来我决定展示一下,你如何(几乎)做对:

var请求\u生成器={
工作:假,
队列:[],
输出:[],
requestData:函数(inputList){
if(request_maker.working==true){
返回false;
}
请求_maker.output=[];
请求_maker.working=true;
while(inputList.length>0){
var data=$.trim(inputList.shift());
请求\u maker.queue.push(数据);
}
日志(请求生成者队列);
请求生成者doTheJob();
返回true;
},
doTheJob:function(){
当前_data_to_send=request_maker.queue.shift();
日志(当前要发送的数据);
if(要发送的当前数据类型!=“未定义”&&request\u maker.queue.length>=0){
$.ajax({
url:“/echo/json/”,
cache:false,
方法:“张贴”,
超时时间:2000,
数据:{
requesttype:“getmydata”,
电子邮件:encodeURIComponent(当前数据发送)
},
成功:功能(数据、状态、xhrobject){
console.log(xhrobject);
请求制造商的handleReturnedData(数据);
},
});
}否则{
请求_maker.working=false;
log(“所有数据都已发送”);
}
},
HandlerReturnedData:函数(响应){
控制台日志(响应);
响应=$.trim(组件(响应));
//response='Failed';//取消注释以模拟此类响应
如果(响应=“失败”){
$('#fetchupdatestatus').append('检索您请求的数据时出错!
'); }否则{ $('#fetchupdatestatus').append('返回的项为'+response+'
'); 请求/输出/推送(响应); } 请求生成者doTheJob(); if(request_maker.working==false){ log(“所有请求都已完成”); console.log(请求生成程序输出); } } } inputList=[1,2,3,4,5,6]; if(请求\制造商请求数据(输入列表)){ console.log('startedworking'); } 如果(!request_maker.requestData(inputList)){ log('正在工作,稍后再试'); }
请注意,我已将请求路径更改为JSFIDLE的ajax模拟链接,并将
html()
替换为
append()
调用,以在div中打印文本。这些调用的执行和处理顺序与
inputList
中的相同,但它们不会锁定用户的浏览器<代码>请求制造商。输出的元素顺序也与
输入列表
中的元素顺序相同

请记住,您还需要添加
错误
处理(可能只是一个将“错误”字符串推入
输出
而不是结果的函数),否则任何ajax错误(403/404/502等)都将使其“卡在”工作状态。或者,您可以使用
complete
而不是
success
来检查请求状态

UPD:问题的答案:你不能同时得到这两个。您可以在异步请求之间使用回调并让浏览器重新绘制,或者使请求同步并阻止浏览器,直到代码完成工作

UPD2:实际上有一些关于强制重画的信息,但我不知道它是否对您有效:

前面我的回答是“您做得不对”,但后来我决定展示一下,您如何(几乎)正确地做:

var请求\u生成器={
工作:假,
队列:[],
输出:[],
requestData:函数(inputList){
if(request_maker.working==true){
返回false;
}
请求_maker.output=[];
请求_maker.working=true;
while(inputList.length>0){
var data=$.trim(inputList.shift());
请求\u maker.queue.push(数据);
}
日志(请求生成者队列);
请求生成者doTheJob();
返回true;
},
doTheJob:function(){
当前_data_to_send=request_maker.queue.shift();
日志(当前要发送的数据);
if(要发送的当前数据类型!=“未定义”&&request\u maker.queue.length>=0){
$.ajax({
url:“/echo/json/”,
cache:false,
方法:“张贴”,
超时时间:2000,
数据:{
requesttype:“getmydata”,
电子邮件:encodeURIComponent(当前数据发送)
},
成功:功能(数据、状态、xhrobject){
console.log(xhrobject);
请求制造商的handleReturnedData(数据);
},
});
}否则{
请求_maker.working=false;
log(“所有数据都已发送”);
}
},
手推车
var request_maker = {
  working: false,
  queue: [],
  output: [],
  requestData: function(inputList) {
    if (request_maker.working == true) {
      return false;
    }
    request_maker.output = [];
    request_maker.working = true;
    while (inputList.length > 0) {
      var data = $.trim(inputList.shift());
      request_maker.queue.push(data);
    }
    console.log(request_maker.queue);
    request_maker.doTheJob();
    return true;
  },

  doTheJob: function() {
    current_data_to_send = request_maker.queue.shift();
    console.log(current_data_to_send);

    if (typeof current_data_to_send != 'undefined' && request_maker.queue.length >= 0) {


      $.ajax({
        url: '/echo/json/',
        cache: false,
        method: "post",
        timeout: 2000,
        data: {
          requesttype: "getmydata",
          email: encodeURIComponent(current_data_to_send)
        },
        success: function(data, status, xhrobject) {
          console.log(xhrobject);
          request_maker.handleReturnedData(data);

        },
      });
    } else {
      request_maker.working = false;
      console.log('all data has been sent');
    }
  },
  handleReturnedData: function(response) {
    console.log(response);
    response = $.trim(decodeURIComponent(response));
    //response= 'Failed';//uncomment to emulate this kind of response
    if (response == "Failed") {
      $('#fetchupdatestatus').append('There was an error retrieving the data you requested!<br/>');
    } else {
      $('#fetchupdatestatus').append('The item returned was ' + response + '<br/>');
      request_maker.output.push(response);
    }
    request_maker.doTheJob();
    if (request_maker.working == false) {
      console.log('all requests have been completed');
      console.log(request_maker.output);
    }
  }
}

inputList = [1, 2, 3, 4, 5, 6];
if (request_maker.requestData(inputList)) {
  console.log('started working');
}

if (!request_maker.requestData(inputList)) {
  console.log('work in progress, try again later');
}