Search code examples
javascriptjqueryajaxgoogle-chrome-extensionget

Error: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience


I am developing a chrome extension in which on button click I need data from ajax GET and after that need to go for further processing. For that, I want synchronous ajax call, but it is giving me an error

Error: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects on the end user's experience.

I know this error is because I set async=false, but unless and until I don't get data from API, I cannot go for further processing. Below is my code:

var nonce;
window.addEventListener('load', function load(event){
    var createButton = document.getElementById('send');
    createButton.addEventListener('click', function() { 
       signTransaction('abc',12,'abc');
    });
});
function signTransaction(to,amount,inputhex){
    nonce = getNonce();
    console.log(nonce);
    tx = {
        To : to,
        PrivateKey : pri,
        Balance : amount,
        Nonce : String(nonce),
        Gas : "1",
        Type : "a64",
        Input : inputhex
    }  
    let transaction = new sdag.Signs.NewTransaction(pri,tx);
}
function getNonce() {
    var request = new XMLHttpRequest();
    request.open('GET', 'http://192.168.xx.xx:9999/getAccount?address=xxxxxxxxx', false);
    request.onload = function () {
      var data = JSON.parse(this.response);
      if (request.status >= 200 && request.status < 400) {
        nonce = data.Nonce;
      } else {
        console.log('error');
      }
    }
    // Send request
    request.send(null);
    return nonce;
   }

You can check in code, In signTransaction() first I need nonce from getNonce() function and then can go further. So, I set async false to this function. Can somebody help me with this?


Solution

  • Per MDN:

    Do not use synchronous requests outside Web Workers.
    

    You could adjust the logic between the two functions such that you define signTransaction() to take in the output of your XML request, then nest signTransaction within getNonce. In that sense, getNonce becomes the controller and signTransaction is an intermediate output back into getNonce.

    function signTransaction(to,amount,inputhex, nonceResponse){
        let tx = {
            To : to,
            PrivateKey : pri,
            Balance : amount,
            Nonce : String(nonce),
            Gas : "1",
            Type : "a64",
            Input : inputhex
        }  
        let transaction = new sdag.Signs.NewTransaction(pri,tx);
        return transaction
    
    
    }
    
    function getNonce(to,amount,inputhex) {
        var request = new XMLHttpRequest();
        request.open('GET', 'http://192.168.51.212:9999/getAccount? 
                             address=23471aa344372e9c798996aaf7a6159c1d8e3eac', true);
    //third arg to request.open() could be omitted if intent is to process call asynchronously
        request.onload = function () {
          var data = JSON.parse(this.response);
          if (request.status >= 200 && request.status < 400) {
            nonce = data.Nonce;
            return signTransaction(to,amount,inputhex,data)
          } else {
            console.log('error');
          }
    }
    

    You could also use ES6 async/await syntax to take advantage of promises and yield program flow during completion of async operations:

    
    async function signTransaction(to,amount,inputhex){
        nonce = await getNonce(); // `await` call yields flow back to the thread while the other async function getNonce() is executed
        tx = {
            To : to,
            PrivateKey : pri,
            Balance : amount,
            Nonce : String(nonce),
            Gas : "1",
            Type : "a64",
            Input : inputhex
        }  
        let transaction = new sdag.Signs.NewTransaction(pri,tx);
    }
    
    async function getNonce() {
        var request = new XMLHttpRequest();
        request.open('GET', 'http://192.168.51.212:9999/getAccount?address=23471aa344372e9c798996aaf7a6159c1d8e3eac', true);
    //third arg to request.open() could be omitted if intent is to process call asynchronously
        request.onload = function () {
          var data = JSON.parse(this.response);
          if (request.status >= 200 && request.status < 400) {
            nonce = data.Nonce;
            return nonce; // returning here resolves the promise that is implicitly returned from an async function with the value returned from your XML call.  This value triggers continuation of the signTransaction function with XML call result
          } else {
            console.log('error');
          }
        }
        // Send request
        request.send(null);
    }