当主获取的结果是循环中的特定值时,如何使用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)

在名为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)
  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()
构造。在白天(使用负功率值),这运行正常。仍然需要在夜间进行测试。