首页 > 解决方案 > 从两个 API 获取数据以将它们合并到一个表中

问题描述

首先,

您可以在下面看到,我的工作程序从两个不同表中的两个不同 API 获取数据。

第一个表包含来自 API 的数据:{Cycle, Delegated Stack, Share, expected payment} 第二个表从另一个 API 获取数据以获取:{the cycle, paid reward} https ://codepen.io/alexand92162579/pen/arJqmv?editors=1010

第二支Code pen是一样的,但是我想根据循环的值合并两个表: https ://codepen.io/alexand92162579/pen/OGdjLJ?editors=1011

根据我在网上阅读的内容,我需要使用 Promises。我已经尝试过多次,但从未成功过!

要尝试它,请KT19www5fiQNAiqTWrugTVLm9FB3th5DzH54在输入框中输入密钥。

如果有人帮助我,我将捐赠 30xtz。

  // Fonction to fetch the data for every cycle on the first API
  // Data Recolted (Cycle, Balance, Share, Expected Reward, Fee, Status)
  // Try to merge with the second table according to the value of cycle
  // // KT19www5fiQNAiqTWrugTVLm9FB3th5DzH54 */

 function calculate2() {
var obj, dbParam, xmlhttp, myObj, x, txt = "";
obj = { table: "cycle", limit: 10 };
dbParam = JSON.stringify(obj);
xmlhttp = new XMLHttpRequest();
var KT1 = $('#KT1').val();
console.log(KT1);
xmlhttp.onreadystatechange = function() {

  Qfee = 0.08;

  if (this.readyState == 4 && this.status == 200) {
    myObj = JSON.parse(this.responseText);
    txt += "<table><tr bgcolor=#000000 color=White>"
    txt += "<th>Cycle</th>"
    txt += "<th>Balance</th>"
    txt += "<th>Share</th>"
    txt += "<th>Reward</th>"
    txt += "<th>Fee</th>"
    txt += "<th>Status</th>"
    txt += "</tr>"

          for (x in myObj) {
            cycle = myObj[x].cycle;
            balance = myObj[x].balance/1000000;
            TotalReward = myObj[x].rewards/1000000;
            status = myObj[x].status.status;
            stakingBalance = myObj[x].staking_balance/1000000;
            Share = balance/stakingBalance*100;
            Fee = Share*TotalReward*Qfee/100;
            DelegatorReward = Share*TotalReward/100 - Fee;

            txt += "<tr>";
            txt += "<td width=10% align=center>" + cycle + "</td>";
            txt += "<td width=25% align=center>" + Math.round(balance*100)/100 + "</td>";
            txt += "<td width=10% align=center>" + Math.round(Share*10)/10 + " %" + "</td>";
            txt += "<td width=10% align=center>" + Math.round(DelegatorReward*100)/100 + "</td>";
            txt += "<td width=10% align=center>" + Math.round(Qfee*1000)/10 + " %"  + "</td>";
            txt += "<td width=30% align=left>" + status + "</td>";
            txt += "</tr>";


    }
        txt += "</table>";    
        document.getElementById("demo").innerHTML = txt;
      }
  };
xmlhttp.open("POST", "https://api6.tzscan.io/v3/delegator_rewards_with_details/" + KT1, true);
xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xmlhttp.send("x=" + dbParam);
}

  /*Fonction to fetch the data for every cycle on the second API
  // Data Recolted (Cycle, Payment)
  // Try to merge with the first table according to the value of cycle
  // // KT19www5fiQNAiqTWrugTVLm9FB3th5DzH54*/
  function calculate3() {
    var obj, dbParam, xmlhttp, myObj, x, txt = "";
    obj = { table: "cycle", limit: 10 };
    dbParam = JSON.stringify(obj);
    xmlhttp = new XMLHttpRequest();
    var KT1 = $('#KT1').val();
    //console.log(KT1);
    xmlhttp.onreadystatechange = function() {

      if (this.readyState == 4 && this.status == 200) {
        myObj = JSON.parse(this.responseText);

        txt += "<table><tr bgcolor=#000000 color=White>"
        //txt += "<th>Block</th>"
        txt += "<th>Cycle</th>"
        txt += "<th>Paid</th>"
        txt += "</tr>"

//If one transaction has been done for the cycle get from the API request 1 then I put the data on the last column of the table
         for (var x = 0; x < 30; x++) {
                if (KT1 == myObj[x].type.operations[0].destination.tz) {
                  console.log("Get one");
                  Block = myObj[x].type.operations[0].op_level;
                  console.log(Block);
                  PaiementCycle = Math.round(Block/4096);
                  PaiementCycle = PaiementCycle - 6;
                  console.log(PaiementCycle);
                  Paid = myObj[x].type.operations[0].amount/1000000;
                  console.log(Paid);
                txt += "<tr>";
                //txt += "<td width=10% align=center>" + Block + "</td>";
                txt += "<td width=10% align=center>" + PaiementCycle + "</td>";
                txt += "<td width=25% align=center>" + Paid + "</td>";
                txt += "</tr>";
                  console.log(txt);
                } else {
                 //console.log("Next");
                }

              }
        txt += "</table>";    
        document.getElementById("demo2").innerHTML = txt;
        return txt;
console.log("ici :" + xmlhttp);

      }
  };

xmlhttp.open("POST", "https://api6.tzscan.io/v3/operations/tz1XynULiFpVVguYbYeopHTkLZFzapvhZQxs?type=Transaction&number=100", true);
xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xmlhttp.send("x=" + dbParam);
}


        $(function () {
            /*when #tezos input loses focus, as per original question*/
            $('#KT1').blur(function () {
              calculate3();
               calculate2();
              console.log(back)
            });
            $('#KT1').change(function () {
                calculate3();
              calculate2();
            });
            $('#KT1').on(function () {
                calculate3();
              calculate2();
            });
            $('#KT1').keyup(function () {
                calculate3();
              calculate2();

            });
            $('#KT1').keydown(function () {
                calculate3();              
              calculate2();
            });
        });


</script>

标签: javascriptpromise

解决方案


未经测试-但我认为这可能会有所帮助-我还尝试减小函数大小以提高可读性;)

function getAndLogKT1(){

    var KT1 = document.querySelector('#KT1')
    console.log(KT1 && KT1.textContent)
    return KT1 && KT1.textContent
}
function firstApiReadystatechange(){

    
}
function createTable(){

    return document.createElement('table');
}

function addTableHeader(table, keys){

    var thead = document.createElement('thead');
    var tr = document.createElement('tr');
    for(var i = 0; i < keys.length; i++){

        var th = document.createElement('th')
        var text = document.createTextNode(keys[i])
        th.appendChild(text)
        tr.appendChild(th)
    }
    thead.appendChild(tr)
    table.appendChild(thead)
}


function addRowToTableBody(table, rowItems){

    var body = table.querySelector('tbody')
    if(!body){

        body = document.createElement('tbody')
        table.appendChild(body)
    }
    var tr = document.createElement('tr')
    for(var i = 0; i < rowItems.length; i++){

        var td = document.createElement('td')
        var text = document.createTextNode(rowItems[i])
        td.appendChild(text)
        tr.appendChild(td)
    }
    body.appendChild(tr)
}

function getDbParam(dbParmaObj){

    return JSON.stringify(dbParmaObj)
}
function sendRequestFirstApi(xmlhttp, KT1, dbParam){

    xmlhttp.open("POST", "https://api6.tzscan.io/v3/delegator_rewards_with_details/" + KT1, true);
    xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    xmlhttp.send("x=" + dbParam);
}
function fetchDataForEveryCycleOnFirstApi(){

    return new Promise((resolve, reject) => {


        var xmlhttp = new XMLHttpRequest();
        xmlhttp.onreadystatechange = function(){
    
            var Qfee = 0.08;
            if(this.readyState === 4 && this.status === 200){
    
                try {
                    var responseObj = JSON.parse(this.responseText)

                    resolve(responseObj)
                } catch {

                    reject({err: "json parse error"})
                }
            }
        }    
        sendRequestFirstApi(xmlhttp, getAndLogKT1(), getDbParam({table: "cycle", limit: 10}))
    })
}
function sendRequestSecondApi(xmlhttp, dbParam){
    xmlhttp.open("POST", "https://api6.tzscan.io/v3/operations/tz1XynULiFpVVguYbYeopHTkLZFzapvhZQxs?type=Transaction&number=100", true);
    xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    xmlhttp.send("x=" + dbParam);
}
function fetchDataForEveryCycleOnSecondApi(){

    return new Promise((resolve, reject) => {


        var xmlhttp = new XMLHttpRequest();
        xmlhttp.onreadystatechange = function(){
    
            var Qfee = 0.08;
            if(this.readyState === 4 && this.status === 200){
    
                try {
                    var responseObj = JSON.parse(this.responseText)

                    resolve(responseObj)
                } catch {

                    reject({err: "json parse error"})
                }
            }
        }    
        sendRequestSecondApi(xmlhttp, getDbParam({table: "cycle", limit: 10}))
    })
}
function parseObjectCycleHashed(respObject){

    var retObj = {}
    for(var x in respObject){

        retObj[respObject[x]['cycle']] = respObject[x]
    }
    return retObj
}
function mergeCycleHashedResponseObjects(a,b){

    let cyclesA = Object.keys(a)
    
    var retObj = Object.assign({}, b)
    for(var i = 0; i < cyclesA.length; i++){

        Object.assign(retObj, {[cyclesA[i]]: a[cyclesA[i]] })
    }
    return retObj
}
function addToDOM(element, querySelector){

    var el = document.querySelector(querySelector)
    el && el.appendChild(element)
}
async function main(){

    var responseObjApiOne = await fetchDataForEveryCycleOnFirstApi();
    var responseObjApiTwo = await fetchDataForEveryCycleOnSecondApi();
    var responseObjApiOneCycleBased = parseObjectCycleHashed(responseObjApiOne);
    var responseObjApiTowCycleBased = parseObjectCycleHashed(responseObjApiTwo);
    var mergedObject = mergeCycleHashedResponseObjects(responseObjApiOneCycleBased, responseObjApiTowCycleBased)
    var table = createTable()
    const headerKeys = [
        "Cycle",
        "Balance",
        "Share",
        "Reward",
        "Fee",
        "Status",
        "Paid"
    ]
    addTableHeader(table, headerKeys)
    for(var cycle in mergedObject){

        addRowToTableBody(table, headerKeys.map(columnTitle => {

            return mergedObject[cycle][columnTitle]
        }))
    }

    addToDOM(table, "dmeo2")
}


推荐阅读