首页 > 解决方案 > 解决拨打电话时反应冻结的问题

问题描述

我正在尝试设置一个微调器,而我的反应应用程序会打几个电话。我正在用 web3 和 solidity 编写一个 Dapp。在调用我的智能合约时,我尝试设置状态以显示微调器,但是整个应用程序在调用合约时冻结,在调用并返回值后,它会设置微调器并快速取消设置微调器(您可以看到值更改控制台记录布尔值)。该应用程序解冻并继续。如何在拨打电话时设置微调器并使应用程序不冻结:

onSubmit(e) {
    e.preventDefault();
    // inProcessOfCalling sh
    this.setState({ inProcessOfCalling: true });
    ...
    const contractData = callContract(parseTestJson.steps, web3);
    Promise.all(contractData).then((values) => {
        ...
        // turn spinner off
        this.setState({ inProcessOfCalling: false });
    });
}

function callContract(callInfo, web3) {
    const dataArr = [];
    for (let i = 0; i < callInfo.length; i += 1) {
        // ...
        const getData = thisContract[callInfo[i].func].getData(
            ...callInfo[i].args,
            { from: callInfo[i].from },
        );
        // ...
        const trans = web3.eth.sendTransaction({
          to: callInfo[i].contract,
          from: callInfo[i].from,
          data: getData,
        });
        let receipt = web3.eth.getTransactionReceipt(trans);
        returnObj = {
          receipt,
          testName: callInfo[i].name,
          expectPassed: callInfo[i].expects.success === transactionPassed,
          expectMessage: callInfo[i].expects.message,
        };
        dataArr.push({ error: false, returnObj });
    }
    return dataArr;
}

我不认为这是一个 web3 问题。我认为它会通过对 API 进行任何多次 fetch 调用来冻结应用程序。

标签: javascriptreactjssolidityweb3

解决方案


您已经在调用callContract很重的函数和这里的请求 <- 这是导致hang

const contractData = callContract(parseTestJson.steps, web3); 在你把它放入 Promise.all 之前它已经被调用了

并且contractData根本不是 Promise,您可以做的是在该函数中返回一个 Promise 对象,如下所示

function callContract(callInfo, web3) {
  return new Promise((resolve, reject) => {
      const dataArr = [];
      for (let i = 0; i < callInfo.length; i += 1) {
        // ...
        const getData = thisContract[callInfo[i].func].getData(
          ...callInfo[i].args, {
            from: callInfo[i].from
          },
        );
        // ...
        const trans = web3.eth.sendTransaction({
          to: callInfo[i].contract,
          from: callInfo[i].from,
          data: getData,
        });
        let receipt = web3.eth.getTransactionReceipt(trans);
        returnObj = {
          receipt,
          testName: callInfo[i].name,
          expectPassed: callInfo[i].expects.success === transactionPassed,
          expectMessage: callInfo[i].expects.message,
        };
        dataArr.push({
          error: false,
          returnObj
        });
      }
      resolve(dataArr);
    }
  }

在此处了解有关承诺的更多信息https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise


推荐阅读