javascript - 从两个 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>
解决方案
未经测试-但我认为这可能会有所帮助-我还尝试减小函数大小以提高可读性;)
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")
}
推荐阅读
- python - AttributeError:“SpooledTemporaryFile”对象没有属性“翻译”
- webpack - [Vue 警告]:uglify 后组件名称无效
- angular - 在 ngFor 中处理 textarea 输入
- ios - UIView 是否可见?
- php - PHP根据值连续遍历数组
- r - 每年每种类型有多少计数?使用 group_by() 或 Split()
- angular - 无法读取未定义的属性“名称”-Angular 6。所有字段都重复错误
- c# - c# Linq 获取实体查询中列表元素的id
- c# - 如何分离 NCrunch 节点服务使用的所有 LocalDb 数据库
- php - MSSQL 连接在第二次或下一次尝试时失败