错误:不赞成在主线程上使用同步XMLHttpRequest,因为它对最终用户的体验有不利影响

时间:2019-05-27 03:27:09

标签: javascript jquery ajax google-chrome-extension get

我正在开发一个 chrome扩展名,在该扩展名中,单击按钮时我需要来自 ajax GET 的数据,然后需要进行进一步处理。为此,我想要同步ajax调用,但这给了我一个错误

  

错误:不赞成在主线程上使用同步XMLHttpRequest   因为它对最终用户的体验有不利影响。

我知道此错误是因为我设置了 async = false ,但是除非并且直到我没有从API获取数据,否则我无法进行进一步处理。下面是我的代码:

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;
   }

您可以检入代码,首先在signTransaction()中需要getNonce()函数的随机数,然后可以继续。因此,我为此功能设置了false异步。 有人可以帮我吗?

1 个答案:

答案 0 :(得分:1)

MDN

Do not use synchronous requests outside Web Workers.

您可以调整两个函数之间的逻辑,以便定义signTransaction()来接收XML请求的输出,然后将signTransaction嵌套在getNonce中。从这种意义上说,getNonce成为控制器,而signTransaction是返回到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');
      }
}

您还可以使用ES6异步/等待语法来在异步操作完成期间利用Promise并产生程序流:


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);
}