Подождите, пока все запросы JQuery Ajax не будут выполнены?

Как сделать функцию до тех пор, пока все запросы jQuery Ajax не будут выполнены внутри другой функции?

Короче говоря, мне нужно дождаться, когда все запросы Ajax будут выполнены до того, как я буду выполнять следующий. Но как?

Ответ 1

jQuery теперь определяет функцию when для этой цели.

Он принимает любое количество отложенных объектов в качестве аргументов и выполняет функцию, когда все они разрешаются.

Это означает, что если вы хотите инициировать (например) четыре запроса ajax, а затем выполнить действие, когда они будут выполнены, вы можете сделать что-то вроде этого:

$.when(ajax1(), ajax2(), ajax3(), ajax4()).done(function(a1, a2, a3, a4){
    // the code here will be executed when all four ajax requests resolve.
    // a1, a2, a3 and a4 are lists of length 3 containing the response text,
    // status, and jqXHR object for each of the four ajax calls respectively.
});

function ajax1() {
    // NOTE:  This function must return the value 
    //        from calling the $.ajax() method.
    return $.ajax({
        url: "someUrl",
        dataType: "json",
        data:  yourJsonData,            
        ...
    });
}

На мой взгляд, он обеспечивает чистый и понятный синтаксис и позволяет избежать любых глобальных переменных, таких как ajaxStart и ajaxStop, которые могут иметь нежелательные побочные эффекты при разработке вашей страницы.

Если вы не знаете заранее, сколько аргументов ajax вам нужно подождать (т.е. Вы хотите использовать переменное количество аргументов), это все равно можно сделать, но это немного сложнее. См. " Передать" в массиве "Отложенные" до $.when() (и, возможно, jQuery. При устранении неполадок с переменным числом аргументов).

Если вам нужно более глубокое управление режимами сбоев сценариев ajax и т.д., Вы можете сохранить объект, возвращаемый .when() - это объект jQuery Promise, охватывающий все исходные запросы ajax. Вы можете позвонить .then() или .fail() чтобы добавить подробные обработчики успеха/отказа.

Ответ 2

Если вы хотите дождаться завершения всех запросов ajax в вашем документе, независимо от того, сколько из них существует, просто используйте событие $.ajaxStop таким образом:

  $(document).ajaxStop(function () {
      // 0 === $.active
  });

В этом случае нет необходимости угадывать, сколько запросов может быть в приложении, которое может завершиться в будущем. В некоторых случаях запросы ajax могут быть частью внутренней логики функции, которая может быть довольно сложной (например, вызов других функций), и в этом случае вы можете не дождаться, когда эта функция будет выполнена со всей логикой, а не только для ожидания ajax для завершения.

$.ajaxStop здесь также может быть привязан к любому узлу HTML который, по вашему мнению, может быть изменен ajax.

Опять же, цель этого обработчика - знать, когда нет активного ajax чтобы не очистить или не перезагрузить что-то.

PS Если вы не против использования синтаксиса ES6, вы можете использовать Promise.all для известных методов ajax. Пример:

Promise.all([ajax1(), ajax2()]).then(() => {
 // all requests finished successfully
}).catch(() => {
 // all requests finished but one or more failed
})

Интересным моментом здесь является то, что он работает как с Promises и с запросами $.ajax. Вот jsFiddle, демонстрирующий последний.

Ответ 3

Я нашел хороший ответ gnarf, который я точно искал:)

jQuery ajaxQueue

//This handles the queues    
(function($) {

  var ajaxQueue = $({});

  $.ajaxQueue = function(ajaxOpts) {

    var oldComplete = ajaxOpts.complete;

    ajaxQueue.queue(function(next) {

      ajaxOpts.complete = function() {
        if (oldComplete) oldComplete.apply(this, arguments);

        next();
      };

      $.ajax(ajaxOpts);
    });
  };

})(jQuery);

Затем вы можете добавить запрос ajax в очередь следующим образом:

$.ajaxQueue({
        url: 'page.php',
        data: {id: 1},
        type: 'POST',
        success: function(data) {
            $('#status').html(data);
        }
    });

Ответ 4

ПРИМЕЧАНИЕ.. В приведенных выше ответах используются функциональные возможности, которых не было в то время, когда этот ответ был написан. Я рекомендую использовать jQuery.when() вместо этих подходов, но я оставляю ответ в исторических целях.

-

Вероятно, вы могли бы справиться с простым семафором подсчета, хотя то, как вы его реализуете, зависит от вашего кода. Простым примером может быть что-то вроде...

var semaphore  = 0,     // counting semaphore for ajax requests
    all_queued = false; // bool indicator to account for instances where the first request might finish before the second even starts

semaphore++;
$.get('ajax/test1.html', function(data) {
    semaphore--;
    if (all_queued && semaphore === 0) {
        // process your custom stuff here
    }
});

semaphore++;
$.get('ajax/test2.html', function(data) {
    semaphore--;
    if (all_queued && semaphore === 0) {
        // process your custom stuff here
    }
});

semaphore++;
$.get('ajax/test3.html', function(data) {
    semaphore--;
    if (all_queued && semaphore === 0) {
        // process your custom stuff here
    }
});

semaphore++;
$.get('ajax/test4.html', function(data) {
    semaphore--;
    if (all_queued && semaphore === 0) {
        // process your custom stuff here
    }
});

// now that all ajax requests are queued up, switch the bool to indicate it
all_queued = true;

Если вы хотите, чтобы это работало как {async: false}, но вы не хотели блокировать браузер, вы могли бы сделать то же самое с очередью jQuery.

var $queue = $("<div/>");
$queue.queue(function(){
    $.get('ajax/test1.html', function(data) {
        $queue.dequeue();
    });
}).queue(function(){
    $.get('ajax/test2.html', function(data) {
        $queue.dequeue();
    });
}).queue(function(){
    $.get('ajax/test3.html', function(data) {
        $queue.dequeue();
    });
}).queue(function(){
    $.get('ajax/test4.html', function(data) {
        $queue.dequeue();
    });
});

Ответ 5

Используйте событие ajaxStop.

Например, скажем, у вас есть сообщение Загрузка... при извлечении 100 аякс-запросов и вы хотите скрыть это сообщение после загрузки.

Из jQuery doc:

$("#loading").ajaxStop(function() {
  $(this).hide();
});

Обратите внимание, что он будет ожидать выполнения всех аякс-запросов на этой странице.

Ответ 6

javascript основан на событиях, поэтому вы никогда не должны ждать, а установите привязки/обратные вызовы

Вероятно, вы можете просто использовать методы успеха/завершения jquery.ajax

Или вы можете использовать . ajaxComplete:

$('.log').ajaxComplete(function(e, xhr, settings) {
  if (settings.url == 'ajax/test.html') {
    $(this).text('Triggered ajaxComplete handler.');
    //and you can do whatever other processing here, including calling another function...
  }
});

хотя вы должны опубликовать псевдокод о том, как ваши запросы (а) ajax называются точными...

Ответ 7

Небольшое обходное решение выглядит примерно так:

// Define how many Ajax calls must be done
var ajaxCalls = 3;
var counter = 0;
var ajaxCallComplete = function() {
    counter++;
    if( counter >= ajaxCalls ) {
            // When all ajax calls has been done
        // Do something like hide waiting images, or any else function call
        $('*').css('cursor', 'auto');
    }
};

var loadPersons = function() {
        // Show waiting image, or something else
    $('*').css('cursor', 'wait');

    var url = global.ctx + '/loadPersons';
    $.getJSON(url, function(data) {
            // Fun things
    })
    .complete(function() { **ajaxCallComplete();** });
};

var loadCountries = function() {
    // Do things
    var url = global.ctx + '/loadCountries';
    $.getJSON(url, function(data) {
            // Travels
    })
    .complete(function() { **ajaxCallComplete();** });
};

var loadCities = function() {
    // Do things
    var url = global.ctx + '/loadCities';
    $.getJSON(url, function(data) {
            // Travels
    })
    .complete(function() { **ajaxCallComplete();** });
};

$(document).ready(function(){
    loadPersons();
    loadCountries();
    loadCities();
});

Надежда может быть полезна...

Ответ 8

jQuery позволяет указать, хотите ли вы, чтобы запрос ajax был асинхронным или нет. Вы можете просто сделать запросы ajax синхронными, а остальная часть кода не будет выполняться до тех пор, пока они не вернутся.

Например:

jQuery.ajax({ 
    async: false,
    //code
});

Ответ 9

На основе ответа @BBonifield я написал функцию утилиты, так что логика семафора не распространяется во всех вызовах ajax.

untilAjax - это функция утилиты, которая вызывает функцию обратного вызова, когда все ajaxCalls завершены.

ajaxObjs - это массив объектов установки ajax [http://api.jquery.com/jQuery.ajax/].

fn - функция обратного вызова

function untilAjax(ajaxObjs, fn) {
  if (!ajaxObjs || !fn) {
    return;
  }
  var ajaxCount = ajaxObjs.length,
    succ = null;

  for (var i = 0; i < ajaxObjs.length; i++) { //append logic to invoke callback function once all the ajax calls are completed, in success handler.
    succ = ajaxObjs[i]['success'];
    ajaxObjs[i]['success'] = function(data) { //modified success handler
      if (succ) {
        succ(data);
      }
      ajaxCount--;
      if (ajaxCount == 0) {
        fn(); //modify statement suitably if you want 'this' keyword to refer to another object
      }
    };
    $.ajax(ajaxObjs[i]); //make ajax call
    succ = null;
  };

Пример: функция doSomething использует untilAjax.

function doSomething() {
  // variable declarations
  untilAjax([{
    url: 'url2',
    dataType: 'json',
    success: function(data) {
      //do something with success data
    }
  }, {
    url: 'url1',
    dataType: 'json',
    success: function(data) {
      //do something with success data
    }
  }, {
    url: 'url2',
    dataType: 'json',
    success: function(response) {
      //do something with success data
    }
  }], function() {
    // logic after all the calls are completed.
  });
}

Ответ 10

Если вам нужно что-то простое; один раз и закончил обратный вызов

        //multiple ajax calls above
        var callback = function () {
            if ($.active !== 0) {
                setTimeout(callback, '500');
                return;
            }
            //whatever you need to do here
            //...
        };
        callback();

Ответ 11

Также вы можете использовать async.js.

Я думаю, что это лучше, чем $., потому что вы можете объединить все виды асинхронных вызовов, которые не поддерживают promises из коробки, такие как таймауты, вызовы SqlLite и т.д., а не просто запросы ajax.

Ответ 12

Я настоятельно рекомендую использовать $. when(), если вы начинаете с нуля.

Несмотря на то, что этот вопрос содержит более миллиона ответов, я до сих пор не нашел ничего полезного для моего дела. Скажем, вам нужно иметь дело с существующей кодовой базой, уже делая некоторые вызовы ajax и не желая вводить сложность promises и/или переделывать все это.

Мы можем легко воспользоваться функциями jQuery .data, .on и .trigger, которые были частью jQuery с тех пор, как навсегда.

Codepen

Хороший материал о моем решении:

  • очевидно, что обратный вызов точно зависит от

  • функция triggerNowOrOnLoaded не заботится, были ли данные уже загружены или мы все еще ждем его

  • его легко подключить к существующему коду

$(function() {

  // wait for posts to be loaded
  triggerNowOrOnLoaded("posts", function() {
    var $body = $("body");
    var posts = $body.data("posts");

    $body.append("<div>Posts: " + posts.length + "</div>");
  });


  // some ajax requests
  $.getJSON("https://jsonplaceholder.typicode.com/posts", function(data) {
    $("body").data("posts", data).trigger("posts");
  });

  // doesn't matter if the `triggerNowOrOnLoaded` is called after or before the actual requests 
  $.getJSON("https://jsonplaceholder.typicode.com/users", function(data) {
    $("body").data("users", data).trigger("users");
  });


  // wait for both types
  triggerNowOrOnLoaded(["posts", "users"], function() {
    var $body = $("body");
    var posts = $body.data("posts");
    var users = $body.data("users");

    $body.append("<div>Posts: " + posts.length + " and Users: " + users.length + "</div>");
  });

  // works even if everything has already loaded!
  setTimeout(function() {

    // triggers immediately since users have been already loaded
    triggerNowOrOnLoaded("users", function() {
      var $body = $("body");
      var users = $body.data("users");

      $body.append("<div>Delayed Users: " + users.length + "</div>");
    });

  }, 2000); // 2 seconds

});

// helper function
function triggerNowOrOnLoaded(types, callback) {
  types = $.isArray(types) ? types : [types];

  var $body = $("body");

  var waitForTypes = [];
  $.each(types, function(i, type) {

    if (typeof $body.data(type) === 'undefined') {
      waitForTypes.push(type);
    }
  });

  var isDataReady = waitForTypes.length === 0;
  if (isDataReady) {
    callback();
    return;
  }

  // wait for the last type and run this function again for the rest of the types
  var waitFor = waitForTypes.pop();
  $body.on(waitFor, function() {
    // remove event handler - we only want the stuff triggered once
    $body.off(waitFor);

    triggerNowOrOnLoaded(waitForTypes, callback);
  });
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<body>Hi!</body>

Ответ 13

Я использую проверку размера, когда вся загрузка ajax завершена

function get_ajax(link, data, callback) {
    $.ajax({
        url: link,
        type: "GET",
        data: data,
        dataType: "json",
        success: function (data, status, jqXHR) {
            callback(jqXHR.status, data)
        },
        error: function (jqXHR, status, err) {
            callback(jqXHR.status, jqXHR);
        },
        complete: function (jqXHR, status) {
        }
    })
}

function run_list_ajax(callback){
    var size=0;
    var max= 10;
    for (let index = 0; index < max; index++) {
        var link = 'http://api.jquery.com/ajaxStop/';
        var data={i:index}
        get_ajax(link,data,function(status, data){
            console.log(index)
            if(size>max-2){
                callback('done')
            }
            size++
            
        })
    }
}

run_list_ajax(function(info){
    console.log(info)
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.1/jquery.min.js"></script>

Ответ 14

Чтобы расширить ответ Алекса, у меня есть пример с переменными аргументами и обещаниями. Я хотел загрузить изображения через ajax и отобразить их на странице после того, как они все загрузятся.

Для этого я использовал следующее:

let urlCreator = window.URL || window.webkitURL;

// Helper function for making ajax requests
let fetch = function(url) {
    return $.ajax({
        type: "get",
        xhrFields: {
            responseType: "blob"
        },
        url: url,
    });
};

// Map the array of urls to an array of ajax requests
let urls = ["https://placekitten.com/200/250", "https://placekitten.com/300/250"];
let files = urls.map(url => fetch(url));

// Use the spread operator to wait for all requests
$.when(...files).then(function() {
    // If we have multiple urls, then loop through
    if(urls.length > 1) {
        // Create image urls and tags for each result
        Array.from(arguments).forEach(data => {
            let imageUrl = urlCreator.createObjectURL(data[0]);
            let img = '<img src=${imageUrl}>';
            $("#image_container").append(img);
        });
    }
    else {
        // Create image source and tag for result
        let imageUrl = urlCreator.createObjectURL(arguments[0]);
        let img = '<img src=${imageUrl}>';
        $("#image_container").append(img);
    }
});

Обновлено для работы с одним или несколькими URL-адресами: https://jsfiddle.net/euypj5w9/

Ответ 15

Как уже упоминалось в других ответах, вы можете использовать ajaxStop(), чтобы дождаться завершения всех запросов ajax.

$(document).ajaxStop(function() {
     // This function will be triggered every time any ajax request is requested and completed
});

Если вы хотите сделать это для конкретного запроса ajax(), лучше всего использовать метод complete() внутри определенного запроса ajax:

$.ajax({
    type: "POST",
    url: "someUrl",
    success: function(data) {
        // This function will be triggered when ajax returns a 200 status code (success)
    },
    complete: function() {
        // This function will be triggered always, when ajax request is completed, even it fails/returns other status code
    },
    error: function() {
        // This will be triggered when ajax request fail.
    }
});


Но, если вам нужно подождать лишь несколько запросов ajax? Используйте замечательные jaascript обещания, чтобы дождаться завершения этих ajax, которые вы хотите ждать. Я сделал короткий, простой и понятный пример, чтобы показать вам, как обещания работают с ajax.
Пожалуйста,посмотрите на следующий пример. Я использовал setTimeout, чтобы прояснить пример.

// Note:
// resolve() is used to mark the promise as resolved
// reject() is used to mark the promise as rejected

$(document).ready(function() {
    $("button").on("click", function() {

        var ajax1 = new Promise((resolve, reject) => {
            $.ajax({
                type: "GET",
                url: "https://miro.medium.com/max/1200/0*UEtwA2ask7vQYW06.png",
                xhrFields: { responseType: 'blob'},
                success: function(data) {
                    setTimeout(function() {
                        $('#image1').attr("src", window.URL.createObjectURL(data));
                        resolve(" Promise ajax1 resolved");
                    }, 1000);
                },
                error: function() {
                    reject(" Promise ajax1 rejected");
                },
            });
        });

        var ajax2 = new Promise((resolve, reject) => {
            $.ajax({
                type: "GET",
                url: "https://cdn1.iconfinder.com/data/icons/social-media-vol-1-1/24/_github-512.png",
                xhrFields: { responseType: 'blob' },
                success: function(data) {
                    setTimeout(function() {
                         $('#image2').attr("src", window.URL.createObjectURL(data));
                         resolve(" Promise ajax2 resolved");
                    }, 1500);
                },
                error: function() {
                    reject(" Promise ajax2 rejected");
                },
            });
        });

        var ajax3 = new Promise((resolve, reject) => {
            $.ajax({
                type: "GET",
                url: "https://miro.medium.com/max/632/1*LUfpOf7teWvPdIPTBmYciA.png",
                xhrFields: { responseType: 'blob' },
                success: function(data) {
                    setTimeout(function() {
                         $('#image3').attr("src", window.URL.createObjectURL(data));
                         resolve(" Promise ajax3 resolved");
                    }, 2000);
                },
                error: function() {
                    reject(" Promise ajax3 rejected");
                },
            });
        });
        
        Promise.all([ajax1, ajax2, ajax3]).then(values => {
            console.log("We waited until ajax ended: " + values);
            console.log("My few ajax ended, lets do some things!!")
        }, reason => {
            console.log("Promises failed: " + reason);
        });
        
        // Or if you want wait for them individually do it like this
        // ajax1.then(values => {
        //    console.log("Promise 1 resolved: " + values)
        // }, reason => {
        //     console.log("Promise 1 failed: " + reason)
        // });
    });

});
img {
  max-width: 200px;
  max-height: 100px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button>Make AJAX request</button>
<div id="newContent">
    <img id="image1" src="">
    <img id="image2" src="">
    <img id="image3" src="">
</div>

Ответ 16

Посмотрите на мое решение:

1.Вставьте эту функцию (и переменную) в файл javascript:

var runFunctionQueue_callback;

function runFunctionQueue(f, index, callback) {

  var next_index = index + 1

  if (callback !== undefined) runFunctionQueue_callback = callback;

  if (f[next_index] !== undefined) {
    console.log(index + ' Next function avalaible -> ' + next_index);
    $.ajax({
      type: 'GET',
      url: f[index].file,
      data: (f[index].data),
      complete: function() {
        runFunctionQueue(f, next_index);
      }
    });
  } else {
    console.log(index + ' Last function');
    $.ajax({
      type: 'GET',
      url: f[index].file,
      data: (f[index].data),
      async: false,
      complete: runFunctionQueue_callback
    });
  }
}

2.Buil массив с вашими запросами, например:

var f = [
           {file: 'file_path', data: {action: 'action', data: 'any_data}},
           {file: 'file_path', data: {action: 'action', data: 'any_data}},
           {file: 'file_path', data: {action: 'action', data: 'any_data}},
           {file: 'file_path', data: {action: 'action', data: 'any_data}}
        ];

3.Создать функцию обратного вызова:

function Function_callback() {
  alert('done');
}

4. Запустите функцию runFunctionQueue с параметрами:

runFunctionQueue(f, 0, QuestionInsert_callback);
// first parameter: array with requests data
// second parameter: start from first request
// third parameter: the callback function

Ответ 18

Мое решение выглядит следующим образом

var request;
...
'services': {
  'GetAddressBookData': function() {
    //This is the primary service that loads all addressbook records 
    request = $.ajax({
      type: "POST",
      url: "Default.aspx/GetAddressBook",
      contentType: "application/json;",
      dataType: "json"
    });
  },

  ...

  'apps': {
    'AddressBook': {
      'data': "",
      'Start': function() {
          ...services.GetAddressBookData();
          request.done(function(response) {
            trace("ajax successful");
            ..apps.AddressBook.data = response['d'];
            ...apps.AddressBook.Filter();
          });
          request.fail(function(xhr, textStatus, errorThrown) {
            trace("ajax failed - " + errorThrown);
          });

Работала довольно хорошо. Я пробовал много разных способов сделать это, но я нашел, что это самый простой и многоразовый. Надеюсь, что это поможет.

Ответ 19

Я нашел простой способ, используя shift()

function waitReq(id)
{
  jQuery.ajax(
  {
    type: 'POST',
    url: ajaxurl,
    data:
    {
      "page": id
    },
    success: function(resp)
    {
      ...........
      // check array length if not "0" continue to use next array value
      if(ids.length)
      {
        waitReq(ids.shift()); // 2
      )
    },
    error: function(resp)
    {
      ....................
      if(ids.length)
      {
        waitReq(ids.shift());
      )
    }
  });
}

var ids = [1, 2, 3, 4, 5];    
// shift() = delete first array value (then print)
waitReq(ids.shift()); // print 1

Ответ 20

$.when не работает для меня, callback(x) вместо return x работал, как описано здесь: fooobar.com/questions/208929/...

Ответ 22

Самое элегантное решение, которое я нашел, которое лучше всего работает с несколькими асинхронными операциями, в отсутствие библиотеки, такой как jQuery или объект, подобный jQuery .when(), заключается в том, чтобы каждый обработчик выполнения Promise приложил обработчик выполнения к одному из других Promises, как это (предполагая, что обещание1, обещание2 и обещание3 являются экземплярами Promise неизвестного состояния):

promise1.then(function(value)
{
    promise2.then(function(value2)
    {
        promise3.then(function(value3)
        {
            doSomethingWithValues(value1, value2, value3);
        }
    }
});

Это работает, потому что выполненные/отклоненные обратные вызовы немедленно срабатывают, если они прикреплены после того, как обещание выполнено или отклонено. Поэтому, даже если promise3 выполняется в первую очередь, его обратный вызов выполнения не будет выполняться до тех пор, пока он не будет присоединен, что не произойдет до тех пор, пока promise1 и promise2 не будут выполнены. Недостатком этого подхода является то, что вложенные выражения функций могут быть немного запутанными. С небольшим количеством рефакторинга мы можем устранить необходимость вложенных функций;

var value1, value2;

function handlePromise1Fulfillment(value)
{
    value1 = value;

    promise2.then(handlePromise2Fulfillment);
}

function handlePromise2Fulfillment(value)
{
    value2 = value;

    promise3.then(handlePromise3Fulfillment);
}

function handlePromise3Fulfillment(value)
{
    doSomethingWithValues(value1, value2, value);
}

promise1.then(handlePromise1Fulfillment);

С этой идиомой мы можем построить неограниченные конъюнкции Promises, не уменьшая удобочитаемость до ужасной степени. И с этой идиомой мы имеем основание для (простой, неполной) when() функции нашей собственной:

function when()
{
    var fulfillmentHandlers = [];
    var values = [];
    var promises = arguments;

    return new Promise(function(resolve, reject)
    { 
        fulfillmentHandlers.push(function(value)
        {
            values.push(value);
            resolve(values.reverse());
        });

        var i;
        // The i declaration in the for loop would be hoisted outside of the loop, but we might as well make this explicit
        for (i = 0; i < promises.length - 1; i++)
        {   
             fulfillmentHandlers[i + 1] = (function(iterator) 
             {
                 return function(value)
                 {
                      values.push(value);
                      promises[iterator].then(fulfillmentHandlers[iterator]);
                 }
             })(i);
        }

        promises[i].then(fulfillmentHandlers[i]);
    });
}

var promise1 = new Promise(function(resolve, reject)
{
    setTimeout(function() { resolve('JavaScript '); }, 5000);
});

var promise2 = new Promise(function(resolve)
{
    setTimeout(function() { resolve('is '); }, 4000);
});

var promise3 = new Promise(function(resolve)
{
    setTimeout(function() { resolve('fun!'); }, 3000);
});

when(promise1, promise2, promise3).then(function(values)
{
    console.log(values[0] + values[1] + values[2]);
});

Ответ 23

Попробуйте этот путь. сделайте цикл внутри java script, чтобы ждать завершения вызова ajax.

function getLabelById(id)
{
    var label = '';
    var done = false;
    $.ajax({
       cache: false,
       url: "YourMvcActionUrl",
       type: "GET",
       dataType: "json",
       async: false,
       error: function (result) {
         label='undefined';
         done = true;
        },
       success: function (result) {
            label = result.Message;
            done = true;
        }
     });

   //A loop to check done if ajax call is done.
   while (!done)
   {
      setTimeout(function(){ },500); // take a sleep.
   }

    return label;
}