Как установить обратный звонок в WEB3 - PullRequest
0 голосов
/ 23 декабря 2018

У меня есть две функции в контракте блокчейна, чтобы получить инвесторов и фонды для адреса, и я попытался сохранить его в Excel.

1-я функция Чтобы получить список инвесторов:

getInvestorsList()

2-я функция Принимает адрес инвестора и возвращает адрес инвестора и средства, сохраненные для этого адреса:

getInvestorsAndBalances(address investorAddress)

Я смогполучить список инвесторов и спонсируемых ими фондов, используя функции "getInvestorsList" и "getInvestorsAndBalances".

Вопрос

  1. Ниже приведен фрагмент, который преобразуетДанные в excel должны выполняться только тогда, когда функция getInvestorsAndBalances полностью выполняется для всех инвесторов.Но этот код выполняется еще до завершения вызова контракта.Поэтому я не получаю значения из блокчейна в приведенный ниже фрагмент кода.

Как заставить приведенный ниже код ожидать успешного завершения функции getInvestorsAndBalances?

                dataSample = dataSample + "]";
                console.log("dataSample: " + dataSample);
                //var dataSample = [{"address": "abc","balance": "21.22"}]; 
                const xls = new XlsExport(dataSample,  'Example WB');  
                xls.exportToXLS('export.xls')  

Полный код

    crowdSaleContractObj.getInvestorsList(function(error, result){
            if(!error)
                {    
                    for (i=0; i < result.length; i++) {  

                        crowdSaleContractObj.getInvestorsAndBalances(result[i],function(error, result1){
                        console.log(i);

                        if(!error)
                            {      
                                console.log(i + " - Address : " + result1[0]+ ",  Balance : " + result1[1]);
                                element = " {\"address\": " + result1[0] + ",balance:" + result1[1] + "},";
                                console.log("element: " + element);
                                dataSample = dataSample + element;
                            }
                        else
                            console.error(error);
                        });   
                    }

                    dataSample = dataSample + "]";
                    console.log("dataSample: " + dataSample);
                    //var dataSample = [{"address": "abc","balance": "21.22"}]; 
                    const xls = new XlsExport(dataSample,  'Example WB');  
                    xls.exportToXLS('export.xls')  

                }
            else
                console.error(error);
    });  

1 Ответ

0 голосов
/ 24 декабря 2018

Вот версия вашего кода, которая работает:

crowdSaleContractObj.getInvestorsList(function(error, results) {
  if (!error) {
    const promises = results.map(function(result, i) {
      return new Promise((resolve, reject) => {
        crowdSaleContractObj.getInvestorsAndBalances(result[i], function(
          error,
          result1
        ) {
          console.log(i);

          if (!error) {
            console.log(
              i + " - Address : " + result1[0] + ",  Balance : " + result1[1]
            );
            resolve(result1);
          } else {
            console.error(error);
            reject(error);
          }
        });
      });
    });

    Promise.all(promises)
      .then(function(results1) {
        results1.forEach(r => {
          element = ' {"address": ' + r[0] + ",balance:" + r[1] + "},";
          console.log("element: " + element);
          dataSample = dataSample + element;
        });
        dataSample = dataSample + "]";
        console.log("dataSample: " + dataSample);
        //var dataSample = [{"address": "abc","balance": "21.22"}];
        const xls = new XlsExport(dataSample, "Example WB");
        xls.exportToXLS("export.xls");
      })
      .catch(function(error) {
        console.error(error);
      });
  } else console.error(error);
});
  1. Вместо цикла for я использую Array.map для преобразования результатов вмассив обещаний , которые разрешаются со значением, возвращаемым обратному вызову в getInvestorsAndBalances
  2. На следующем шаге я вызываю Promise.all для этого массиваобещаний;это приводит к тому, что код в методе then выполняется только после асинхронного получения всех инвесторов и балансов

Улучшение кода

I 'Вы позволили себе немного реорганизовать свой код, чтобы использовать возможности современного языка и исправить некоторые ошибки:

crowdSaleContractObj.getInvestorsList((error, results) => {
  if (error) {
    console.error(error);
    return;
  }
  const promises = results.map(
    (result, i) =>
      new Promise((resolve, reject) => {
        crowdSaleContractObj.getInvestorsAndBalances(
          result[i],
          (error, result1) => {
            if (error) {
              reject(error);
              return;
            }
            resolve(result1);
          }
        );
      })
  );

  Promise.all(promises)
    .then(results1 => {
      const dataSample = `[${results1
        .map(r => `{"address": "${r[0]}", "balance": ${r[1]}}`)
        .join(", ")}]`;
      const xls = new XlsExport(dataSample, "Example WB");
      xls.exportToXLS("export.xls");
    })
    .catch(function(error) {
      return console.error(error);
    });
});
  1. Я использую функции стрелок вместо объявлений функций для большегокод consise
  2. Я использую шаблон раннего возврата (проверьте, есть ли ошибка, затем немедленно вернитесь из функции), чтобы избежать слишком глубокого вложения операторов if / else
  3. Я объявляю переменную dataSample с const ;Вы вообще не объявляли это, ни i, ни element, что делало их глобальными переменными - это плохая практика
  4. Я использую строки шаблона для созданиястрока данных для экспорта в XLS
  5. Я исправил проблемы с форматированием в вашей строке данных - он не генерировал допустимый JSON, потому что вас перепутали с кавычками и запятыми
  6. Я использую Array.map для создания строки dataSample в сочетании с Array.join , чтобы избежать проблемы с запятой в конце данных (которая приводила к неверному формату JSON)
  7. Я удалил операторы консоли, предполагая, что вы просто использовали их для отладки
...