当主获取的结果是循环中的特定值时,如何使用JavaScript等待二次获取的结果?
在名为javascript当主获取的结果是循环中的特定值时,如何使用JavaScript等待二次获取的结果?,javascript,json,for-loop,async-await,fetch-api,Javascript,Json,For Loop,Async Await,Fetch Api,在名为javascript函数的计时器中,我需要使用几个jsonapi调用更新UI。 它是一个电能表,将实际消耗的相位功率存储在3个不同的寄存器中。除了负值(太阳能电池板的能量)外,该返回的能量存储在其他3个寄存器中(作为正值)如果相位功率为0,我需要获取备用相位功率寄存器 Loop 3 times Fetch A at api1 If A=0 Then Fetch A at api2 Display A Display min(A) Display max(A)
函数的计时器中,我需要使用几个jsonapi调用更新UI。
它是一个电能表,将实际消耗的相位功率存储在3个不同的寄存器中。除了负值(太阳能电池板的能量)外,该返回的能量存储在其他3个寄存器中(作为正值)如果
相位功率为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(返回的不是0)
我尝试了async
和wait
,比如。因此,更改以下代码中的两行:
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
如果(nvKW==0)执行此块,如何使底部的document.getElementById
(以及下面加载的UI内容)等待第二级(不是第二个循环)获取
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
函数更新()
{
无功相位;
for(让phase=1;phase response.json())
。然后(json=>
{
for(让j在json.fields中){
if(json.fields[j].name.startsWith(“power\u-delivered\u-l”))
{
myPhase=Number(json.fields[j].name.replace('power_delivered_l','');
设nvKW=Number(json.fields[j].value)
if(nvKW==0)//检查是否产生了功率
{
获取(APIGW+“v1/sm/fields/power\u返回的\u l”+myPhase)
.then(response=>response.json())
。然后(json2=>
{
for(让jr进入json2.fields){
if(json2.fields[jr].name.startsWith(“power\u返回的\u l”))
{
让nvKW=-1*个数字(json2.fields[jr].value)
console.log(json2.fields[jr].name+“=”+nvKW.toString())//这里nvKW包含一个值
}
}
}
);
}
console.log(“nvKW=“+nvKW.toString())//第一级获取=0,第二级获取!=0,那么这里nvKW仍然是0,我需要第二级获取的值
document.getElementById(json.fields[j].name).innerHTML=nvKW.toFixed(1);
//下面将做更多的ui工作
然后使用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 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`);
}
然后…您可以将document.getElementById(json.fields[j].name).innerHTML=nvKW.toFixed(1);
放在中。然后(json2=>{})
codeblock@Pipe我无法将document.getElementById(json.fields[j].name).innerHTML=nvKW.toFixed(1);
放在中。然后(json2=>{})
因为当nvKW!=0
时,所有的UI内容都应该被执行。在这种情况下,整个if(){}
代码块被跳过。使用wait
第二次fetch
(在if
块内部)可以工作,您能告诉我们您是如何尝试使用它的吗?或者,请参见。注意外部(一)fetch
及其周围的循环与此问题无关。@Bergi我已在上面的问题中插入了我的async
wait
并尝试返回错误。除了显示值min/max/etcetera外,还必须检查和显示。在这种情况下,所有UI代码都需要复制。也许我可以用一个有趣的方式来包装它然后,在伪代码中,只有名为A的值。在我的示例中,A是json或A是json2(当第一个值等于0时)…然后您可以使用该值执行一个函数来更新所有用户界面..无需重复代码..我将更新我的代码。谢谢您的努力。我仍然更喜欢Bergi的方法。我选择了.Then()
构造。在白天(使用负功率值),这运行正常。仍然需要在夜间进行测试。