簡體   English   中英

如何等待ajax請求?

[英]How to await the ajax request?

我正在嘗試編寫一個 JS 代碼,如果數據庫中已經存在給定的數字,它將取消“btn_submit”按鈕 .onclick 事件。 我使用 AJAX 查詢給定數字的數據庫,並確定是否應該將數據發送到將上傳問題的 .php 站點。 要確定這一點,我需要 numOfRows 變量的值,但因為我在 AJAX 中設置它,它將保持為 0。validation() 函數將在我的 AJAX 查詢完成之前完成,這會導致問題始終表明給定數字不存在於數據庫中(numOfRows 將始終保持為 0)。 在我將驗證()函數的結尾行中的 numOfRows 與 0 進行比較之前,如何等待 AJAX 查詢完成? 如果數據庫中已經存在該數字,我需要將 false 返回到此行:

document.getElementById("btn_submit").onclick = 驗證;

謝謝!

var textAreaList;
var numOfRows = 0;
var finished = false;

document.getElementById("btn_submit").onclick = validation;

textAreaList = document.getElementsByClassName("text_input");

function validation() {
    loadNumRows();

    try {
        document.getElementById('failure').hidden = true;
    }
     catch(e) {
         console.log(e.message);
     }
    textAreaList = document.getElementsByClassName("text_input");
    var failValidation = false;
    for (var i = 0; i < textAreaList.length; i++) {
        console.log(textAreaList[i]);
        if (textAreaList[i].value == "") {
            textAreaList[i].style.border = "2px solid #ff0000";
            failValidation = true;
        } else {
            textAreaList[i].style.border = "2px solid #286C2B";
        }
    }

    return !(failValidation || numOfRows != 0);
}

function loadNumRows(){
    $.ajax({
        url: 'php/SeeIfNumberExists?number=' + document.getElementById('number_inp').value,
        type: "GET",
        cache: false,
        success: function (html) {
           numOfRows = parseInt(html);               
        }
    });
}

async/await與 Babel 之類的編譯器一起使用,以使其在舊瀏覽器中運行。 你還必須從 npm 安裝這個 Babel 預設和 polyfill:

npm i -D babel-preset-env babel-polyfill

然后

function getData(ajaxurl) { 
  return $.ajax({
    url: ajaxurl,
    type: 'GET',
  });
};

async function test() {
  try {
    const res = await getData('https://api.icndb.com/jokes/random')
    console.log(res)
  } catch(err) {
    console.log(err);
  }
}

test();

或者.then回調只是編寫相同邏輯的另一種方式。

getData(ajaxurl).then((res) => {
    console.log(res)
});

使用async: false是一個非常糟糕的主意,並且一開始就違背了使用 AJAX 的全部目的——AJAX 本來就是異步的。 如果您想在進行 AJAX 調用時等待腳本的響應,只需使用延遲對象和承諾:

var validation = function () {
    var numberCheck = $.ajax({
        url: 'php/SeeIfNumberExists?number=' + $('#number_inp').val(),
        type: "GET"
    });

    // Listen to AJAX completion
    numberCheck.done(function(html) {
        var numOfRows = parseInt(html),
            textAreaList = $('.text_input'),
            finished = false;

        // Rest of your code starts here
        try {
            document.getElementById('failure').hidden = true;
        }
        catch(e) {
            console.log(e.message);
        }

        // ... and the rest
    });

}

// Bind events using jQuery
$('#btn_submit').click(validation);

我在您的代碼中看到您正在使用本機 JS 和 jQuery 的混合 - 如果您堅持使用它會有所幫助:)

永遠不要使用async:false它很危險,你的應用程序可能會行為不端。

只有當您的響應返回一個承諾時,您才能使用 await。

不幸的是,jQuery ajax 在完成時不會返回 Promise。

但是您可以在 ajax 請求中使用 Promise 並在完成后返回 Promise。

function asyncAjax(url){
    return new Promise(function(resolve, reject) {
            $.ajax({
                url: url,
                type: "GET",
                dataType: "json",
                beforeSend: function() {            
                },
                success: function(data) {
                    resolve(data) // Resolve promise and when success
                },
                error: function(err) {
                    reject(err) // Reject the promise and go to catch()
                }
            });
    });
}

我們已經將 ajax 調用轉換為 Promise,所以現在我們可以使用 await。

try{
    const result = await asyncAjax('your url');
} catch(e){
    console.log(e);
}

(我承認這不是處理事情的最佳方式,但這是讓您的代碼按原樣運行的最快方式。實際上,您應該重新考慮如何拉取 numOfRows 值,以便它可以與真正的異步 Ajax 一起使用. 話雖這么說...):

首先在$.ajax調用中設置async : false Ajax 中的 A 代表異步 這意味着,執行繼續而不是等待它返回。 您想將其關閉(即使其同步)。 實際上,考慮到您那里的代碼,這應該是整個解決方案。

$.ajax({
        url: 'php/SeeIfNumberExists?number=' + document.getElementById('number_inp').value,
        type: "GET",
        async: false,
        cache: false,
        success: function (html) {
           numOfRows = parseInt(html);               
        }
    });

文檔中對$.ajax的一個警告:

跨域請求和 dataType: "jsonp" 請求不支持同步操作。 請注意,同步請求可能會暫時鎖定瀏覽器,從而在請求處於活動狀態時禁用任何操作。 從 jQuery 1.8 開始,不推薦在 jqXHR ($.Deferred) 中使用 async: false ; 您必須使用成功/錯誤/完成回調選項而不是 jqXHR 對象的相應方法,例如 jqXHR.done() 或已棄用的 jqXHR.success()。

這對我有用

async function doAjax() {
    const result = await $.ajax({
        url: "https://api.exchangerate-api.com/v4/latest/USD",
        type: 'GET',
    });

    return result;
}

async function tt(){
    var res = await doAjax()
    var money = res.rates.INR
    console.log(money)
}

tt()

暫無
暫無

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

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