Web3.js: как эффективно загружать и отображать кучу элементов из блокчейна?

Я разрабатываю DApp и борюсь с эффективной загрузкой из блокчейна и отображением во внешнем интерфейсе. Я загружаю все элементы сразу. Когда список элементов становится очень большим (> 500), интерфейс начинает лагать и загрузка становится довольно медленной (я получаю предупреждения типа «[Нарушение] Принудительное перекомпонование при выполнении JavaScript заняло 87 мс»). На странице есть пагинация и сортировщики/фильтры, поэтому я не могу загружать элементы частично (по индексу), так как не знаю, сколько из них мне понадобится при применении фильтров/сортировщиков.

Вот псевдокод: Solidity:

struct Item {
  uint256 id;
  address owner;
  bool claimed;
}

Item[] private items;
uint256 public numberOfItems;

function getItemInfo(uint256 itemID) public view returns(address owner, bool claimed) {
  Item memory item = items[itemID];

  owner = item.owner;
  claimed = item.claimed;
}

JS (веб3):

loadItems: function(items, account) {
  var contractInstance;

  App.contracts.MyContract.deployed().then(function(instance) {
    contractInstance = instance;
    return contractInstance.numberOfItems.call();
}).then(function(numberOfItems) {
  console.log(Number(numberOfItems));

  for (var i = 0; i < numberOfItems; i++ ){
  contractInstance.getItemInfo(i).then(function(data){
    //console.log(data);
  })
}
}).catch(function(err) {
  console.log(err.message);
});
},

Было бы здорово получить любые предложения о том, как я могу решить эту проблему и эффективно загружать элементы.

Ответы (1)

Чтобы убедиться, что все загружается, вам нужно использовать обещания. Это гарантирует, что ничего не будет перегружено, потому что время истекло. Есть несколько стратегий, вот один пример:

function TotalOwnersPromise(Contract) {
return new Promise((resolve, reject) => {

     Contract.TotalOwners(function (error, result) {
        if (error) {
            reject(error);
            console.log("Total Owners Error");
        } else {

            resolve(result);
            console.log("Owners " + Owners);
        }
         });
     });
};

Что касается огромного количества запросов, которые вы делаете, вам нужно будет запустить свой собственный узел и иметь несколько node.js, отслеживающих события и контракты. Нет никакой гарантии, что infura или etherscan в будущем позволят так много запросов забивать их бесплатно.