当主抓取的结果是循环中的特定值时,如何使用 JavaScript 等待二级抓取结果?
How to wait for secondary fetched result with JavaScript when the result of a primary fetch is a specific value within a loop?
在一个名为 javascript function
的 timer
中,我需要使用多个 json API 调用来更新 UI。
这是一个电能表,将实际消耗的相功率存储在 3 个不同的寄存器中。除了负值(太阳能电池板的能量)外,返回的能量存储在其他 3 个寄存器中(作为正值)。 If
相功率为0,需要取交替相功率寄存器
Loop 3 times
Fetch A at api1
If A=0 Then
Fetch A at api2
Display A
Display min(A)
Display max(A)
Display trend
Even more display stuff I don't want to duplicate
我设法获取了该值,但是无法获取替代的获取值以在 fetch
块下方继续存在。获取 api2 时显示 A = 0(returns 不是 0)。
我尝试了 async
和 await
,比如 。因此更改以下代码中的 2 行:
async function update()
…
await fetch(APIGW+"v1/sm/fields/power_returned_l"+myPhase)
这导致:
Uncaught SyntaxError: await is only valid in async functions and async generators
Uncaught ReferenceError: update is not defined
如何在执行此 if (nvKW == 0 )
块时使底部 document.getElementById
(以及下面的大量 UI 内容)等待第 2 级(不是第 2 循环)获取?
function update()
{
var phase;
for( let phase = 1 ; phase <= PHASES ; phase++ )
{
fetch(APIGW+"v1/sm/fields/power_delivered_l"+phase)
.then(response => response.json())
.then(json =>
{
for( let j in json.fields ){
if (json.fields[j].name.startsWith("power_delivered_l"))
{
myPhase = Number(json.fields[j].name.replace('power_delivered_l',''));
let nvKW=Number(json.fields[j].value)
if (nvKW == 0 ) // check if power is generated
{
fetch(APIGW+"v1/sm/fields/power_returned_l"+myPhase)
.then(response => response.json())
.then(json2 =>
{
for( let jr in json2.fields ){
if (json2.fields[jr].name.startsWith("power_returned_l"))
{
let nvKW=-1*Number(json2.fields[jr].value)
console.log(json2.fields[jr].name+" = "+ nvKW.toString()) // here nvKW contains a value
}
}
}
);
}
console.log("nvKW = "+ nvKW.toString()) // 1st level fetch = 0 and 2nd level fetch != 0 then nvKW is still 0 here, where I need the value from the 2nd level fetch
document.getElementById(json.fields[j].name).innerHTML = nvKW.toFixed(1);
// a lot more ui stuff is done below
然后使用 else:
function updateUIwithA(A){
//Do whatever you need to update UI from A
//document.getElementById("fieldNameForDisplayAValue").innerHTML = getValue(A);
//document.getElementById("fieldNameForDisplayAMin").innerHTML = getMin(A);
//document.getElementById("fieldNameForDisplayAMax").innerHTML = getMax(A);
//document.getElementById("fieldNameForDisplayAverage").innerHTML = getAverage(A);
}
...
let nvKW=Number(json.fields[j].value)
if (nvKW == 0 ) // check if power is generated
{
//First power is 0, then fetch the second power
fetch(APIGW+"v1/sm/fields/power_returned_l"+myPhase)
.then(response => response.json())
.then(json2 =>
{
for( let jr in json2.fields ){
if (json2.fields[jr].name.startsWith("power_returned_l"))
{
//Show second power
let nvKW2=-1*Number(json2.fields[jr].value)
console.log(json2.fields[jr].name+" = "+ nvKW.toString()) // here nvKW contains a value
updateUIwithA(json2);
}
}
}
);
} else {
//First power is not 0, so show the current value and ignore second fetch
updateUIwithA(json);
}
在条件承诺上使用 .then()
语法:
json => {
const field = getFieldByName(json, "power_delivered_l");
const myPhase = field.name.replace('power_delivered_l','');
(field.value == 0 // check if power is generated
? fetch(APIGW+"v1/sm/fields/power_returned_l"+myPhase)
.then(response => response.json())
.then(json2 => getFieldByName(json2, "power_returned_l", -1))
: Promise.resolve(field)
).then(({name, value: nvKW}) => {
console.log(`${name} = ${nvKW}`)
document.getElementById(json.fields[j].name).innerHTML = nvKW.toFixed(1);
// a lot more ui stuff is done below
});
}
使用async
/await
:
async json => {
let field = getFieldByName(json, "power_delivered_l");
if (field.value == 0) // check if power is generated
const myPhase = field.name.replace('power_delivered_l','');
const response = await fetch(APIGW+"v1/sm/fields/power_returned_l"+myPhase);
const json2 = await response.json())
field = getFieldByName(json2, "power_returned_l", -1))
}
const {name, value: nvKW} = field;
console.log(`${name} = ${nvKW}`)
document.getElementById(json.fields[j].name).innerHTML = nvKW.toFixed(1);
// a lot more ui stuff is done below
}
两者都使用辅助函数
function getFieldByName(json, prefix, factor = 1) {
for (const field of json.fields) {
if (field.name.startsWith(prefix)) {
return {
name: field.name,
value: factor * Number(field.value)
};
}
}
throw new Error(`Did not find field '${prefix}' in the JSON`);
}
在一个名为 javascript function
的 timer
中,我需要使用多个 json API 调用来更新 UI。
这是一个电能表,将实际消耗的相功率存储在 3 个不同的寄存器中。除了负值(太阳能电池板的能量)外,返回的能量存储在其他 3 个寄存器中(作为正值)。 If
相功率为0,需要取交替相功率寄存器
Loop 3 times
Fetch A at api1
If A=0 Then
Fetch A at api2
Display A
Display min(A)
Display max(A)
Display trend
Even more display stuff I don't want to duplicate
我设法获取了该值,但是无法获取替代的获取值以在 fetch
块下方继续存在。获取 api2 时显示 A = 0(returns 不是 0)。
我尝试了 async
和 await
,比如
async function update()
…
await fetch(APIGW+"v1/sm/fields/power_returned_l"+myPhase)
这导致:
Uncaught SyntaxError: await is only valid in async functions and async generators
Uncaught ReferenceError: update is not defined
如何在执行此 if (nvKW == 0 )
块时使底部 document.getElementById
(以及下面的大量 UI 内容)等待第 2 级(不是第 2 循环)获取?
function update()
{
var phase;
for( let phase = 1 ; phase <= PHASES ; phase++ )
{
fetch(APIGW+"v1/sm/fields/power_delivered_l"+phase)
.then(response => response.json())
.then(json =>
{
for( let j in json.fields ){
if (json.fields[j].name.startsWith("power_delivered_l"))
{
myPhase = Number(json.fields[j].name.replace('power_delivered_l',''));
let nvKW=Number(json.fields[j].value)
if (nvKW == 0 ) // check if power is generated
{
fetch(APIGW+"v1/sm/fields/power_returned_l"+myPhase)
.then(response => response.json())
.then(json2 =>
{
for( let jr in json2.fields ){
if (json2.fields[jr].name.startsWith("power_returned_l"))
{
let nvKW=-1*Number(json2.fields[jr].value)
console.log(json2.fields[jr].name+" = "+ nvKW.toString()) // here nvKW contains a value
}
}
}
);
}
console.log("nvKW = "+ nvKW.toString()) // 1st level fetch = 0 and 2nd level fetch != 0 then nvKW is still 0 here, where I need the value from the 2nd level fetch
document.getElementById(json.fields[j].name).innerHTML = nvKW.toFixed(1);
// a lot more ui stuff is done below
然后使用 else:
function updateUIwithA(A){
//Do whatever you need to update UI from A
//document.getElementById("fieldNameForDisplayAValue").innerHTML = getValue(A);
//document.getElementById("fieldNameForDisplayAMin").innerHTML = getMin(A);
//document.getElementById("fieldNameForDisplayAMax").innerHTML = getMax(A);
//document.getElementById("fieldNameForDisplayAverage").innerHTML = getAverage(A);
}
...
let nvKW=Number(json.fields[j].value)
if (nvKW == 0 ) // check if power is generated
{
//First power is 0, then fetch the second power
fetch(APIGW+"v1/sm/fields/power_returned_l"+myPhase)
.then(response => response.json())
.then(json2 =>
{
for( let jr in json2.fields ){
if (json2.fields[jr].name.startsWith("power_returned_l"))
{
//Show second power
let nvKW2=-1*Number(json2.fields[jr].value)
console.log(json2.fields[jr].name+" = "+ nvKW.toString()) // here nvKW contains a value
updateUIwithA(json2);
}
}
}
);
} else {
//First power is not 0, so show the current value and ignore second fetch
updateUIwithA(json);
}
在条件承诺上使用 .then()
语法:
json => {
const field = getFieldByName(json, "power_delivered_l");
const myPhase = field.name.replace('power_delivered_l','');
(field.value == 0 // check if power is generated
? fetch(APIGW+"v1/sm/fields/power_returned_l"+myPhase)
.then(response => response.json())
.then(json2 => getFieldByName(json2, "power_returned_l", -1))
: Promise.resolve(field)
).then(({name, value: nvKW}) => {
console.log(`${name} = ${nvKW}`)
document.getElementById(json.fields[j].name).innerHTML = nvKW.toFixed(1);
// a lot more ui stuff is done below
});
}
使用async
/await
:
async json => {
let field = getFieldByName(json, "power_delivered_l");
if (field.value == 0) // check if power is generated
const myPhase = field.name.replace('power_delivered_l','');
const response = await fetch(APIGW+"v1/sm/fields/power_returned_l"+myPhase);
const json2 = await response.json())
field = getFieldByName(json2, "power_returned_l", -1))
}
const {name, value: nvKW} = field;
console.log(`${name} = ${nvKW}`)
document.getElementById(json.fields[j].name).innerHTML = nvKW.toFixed(1);
// a lot more ui stuff is done below
}
两者都使用辅助函数
function getFieldByName(json, prefix, factor = 1) {
for (const field of json.fields) {
if (field.name.startsWith(prefix)) {
return {
name: field.name,
value: factor * Number(field.value)
};
}
}
throw new Error(`Did not find field '${prefix}' in the JSON`);
}