簡體   English   中英

如何保證一個 ajax 調用在調用另一個之前完成?

[英]How can a guarantee one ajax call is complete before calling another?

我正在開發一個 flask 應用程序,並且有這個 javascript function 與表單相關聯

function applyQueries() {
        // does some things
        if(currentCatalog != ''){
            addCatalogFilters(currentCatalog);
        }
        $.ajax({
            type: 'POST',
            url:  "/applyQueries",
            contentType: "application/json",
            success:function(response){ 
                        // does some stuff here
        })
}

addCatalogFilters() function 也是一個 ajax 調用。 這兩個調用都改變了 python 方面的一些變量。 我想知道的是,第一個 ajax 調用(在 addCatalogFilters 中)是否保證在第二個調用之前執行並返回。 根據 ajax 調用的執行順序,我得到了奇怪的結果,這些結果似乎是競爭條件。 像這樣結構的代碼可以做到這一點嗎? 另外,如果是這樣,我該如何解決?

    // Add user catalog filters
    function addCatalogFilters() {
        catalog = currentCatalog;
        formData = new FormData(document.getElementById('catalogFilterForm'));
        $.ajax({
            type: 'POST',
            url:  "/addCatalogFilters",
            data: formData,
            processData: false,
            contentType: false,
            success: function (response){
                document.getElementById(catalog + 'close').style.display = 'block';
                document.getElementById(catalog + 'check').style.display = 'none';
                addBtns = document.getElementsByClassName("addBtn");
                removeBtns = document.getElementsByClassName("removeBtn");
                for (i = 0; i < addBtns.length; i++) {
                    addBtns[i].style.display = "none";
                    removeBtns[i].style.display = "inline-block";
                }
            }
        })
    };

您可以嘗試像這樣使用async/await

async function applyQueries() {

  if(currentCatalog !== ''){
    const filtersAdded = await addCatalogFilters(currentCatalog);
  }

  // Perform AJAX call

}

通過 usinc async/await,您的代碼將等待addCatalogFilters() function 解決。 但是,要使其正常工作, addCatalogFilters() function 應該與返回值異步。 像這樣的東西:

async function addCatalogFilters(catalog){
  // Ajax call
  $.ajax({
        type: 'POST',
        url:  "foo",
        contentType: "application/json",
        success:function(response){ 
          return true
    })

}

您可以確保 ajax 的 function 成功。 First call a ajax (let's say ajax1) then call another ajax call within the success function of first ajax call (ajax1 success function).

addCatalogFilters(currentCatalog)
{
    $.ajax({
            type: 'POST',
            url:  "/the-post-usl",

            success:function(response){ 

                $.ajax({
                type: 'POST',
                url:  "/applyQueries",
                contentType: "application/json",
                success:function(response){ 
                        // does some stuff here
                });
        })
}

function applyQueries() {
        // does some things
        if(currentCatalog != ''){
            addCatalogFilters(currentCatalog);
        }

}

這可能不是最佳方式。 但要保證一個 ajax 調用在調用另一個之前完成。

根據調用 applyQueries 的方式,您可能需要等待或調用它。 請注意,您還可以使用“result = await addCatalogFilters(currentCatalog)”將 ajax 結果放入變量結果中,您可以使用該變量結果並將其傳遞給 applyQueries 中的 $.ajax 調用。 我不知道你的代碼的性質,所以我不能提出任何直接的建議。

async function applyQueries() {
        // does some things
        if(currentCatalog != ''){
            // await on the returned Promise-like jqXHR (wait for ajax request to finish)
            // recommend assigning awaited result to a variable and passing to next $.ajax
            await addCatalogFilters(currentCatalog);
        }
        return $.ajax({
            type: 'POST',
            url:  "/applyQueries",
            contentType: "application/json",
            success:function(response){ 
                        // does some stuff here
        })
}

// Add user catalog filters
function addCatalogFilters() {
    catalog = currentCatalog;
    formData = new FormData(document.getElementById('catalogFilterForm'));
    // return the Promise-like jqXHR object: https://api.jquery.com/jQuery.ajax/#jqXHR
    return $.ajax({
        type: 'POST',
        url:  "/addCatalogFilters",
        data: formData,
        processData: false,
        contentType: false,
        success: function (response){
            document.getElementById(catalog + 'close').style.display = 'block';
            document.getElementById(catalog + 'check').style.display = 'none';
            addBtns = document.getElementsByClassName("addBtn");
            removeBtns = document.getElementsByClassName("removeBtn");
            for (i = 0; i < addBtns.length; i++) {
                addBtns[i].style.display = "none";
                removeBtns[i].style.display = "inline-block";
            }
        }
    })
};

您可以使用async/await 但是,正如沒有人提到的那樣,我想演示如何使用Promise來實現這一點。

讓我們定義兩個函數:

function first_function(data) {

  return new Promise((resolve, reject) => {

    let dataSet = [[]];

    let response;

    $.ajax({
      type: "POST",
      url: 'example.com/xyz',
      async: false,
      data: data,
      success: function (value) {
        response = value;
        dataSet = JSON.parse(response);
        resolve(dataSet)
      },

      error: function (error) {
        reject(error)
      },
      processData: false,
      contentType: false
    });

  })

}


function second_function(data) {

  return new Promise((resolve, reject) => {

    let dataSet = [[]];

    let response;

    $.ajax({
      type: "POST",
      url: 'example.com/abc',
      async: false,
      data: data,
      success: function (value) {
        response = value;
        dataSet = JSON.parse(response);
        resolve(dataSet)
      },

      error: function (error) {
        reject(error)
      },
      processData: false,
      contentType: false
    });

  })

}

現在,您可以通過以下方法確保second_function()僅在first_function()中執行ajax請求后才被調用:

first_function(data)
  .then(dataSet => {
    //do other things
    second_function(dataSet)
      .then(dataSet2 => {
        ////do whatever you like with dataSet2

      })
      .catch(error => {
        console.log(error);
      });

  });

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM