Synchrones VBscript wurde in falsch asynchrones Javascript geändert [Duplikat]

Oct 09 2020

Mein Chef hat mich daher gebeten, ein Problem zu untersuchen, bei dem alte VBscript-Skripte in Javascript-Skripte portiert werden, das Javascript jedoch einen falschen Programmfluss aufweist. Das einzige Problem ist, dass ich beides nicht kenne, aber wenn Ihr Chef Sie fragt, müssen Sie einen Plan machen. ;-);

Im VBscript hatte der Benutzer die Wahl und wenn "Nein", wurde der nächste Bildschirm / die nächste Ansicht nicht angezeigt. Mit Javascript wird jedoch der nächste Bildschirm / die nächste Ansicht geladen, unabhängig davon, ob der Benutzer "Nein / Abbrechen" wählt oder nicht. Dies sollte nicht passieren.

Hier ist das VBscript, der wichtige Teil ist zwischen dem //:

vEffectiveDate  = ScreenForm("smoke.Effective Date").Value
vLastRunDate    = ScreenForm("smoke.Last Run Date").Value
sStatus         = ScreenForm("smoke.Calc Status").Value

vMsg = ""

If Len(sStatus) = 0 Then
    sStatus = "SUCCESFUL"
    ScreenForm("smoke.Calc Status").Value = sStatus
End If

If Len(vEffectiveDate) > 0 Then

    If Not IsDate(vEffectiveDate) Then 
        vMsg = vMsg & "[Effective Date] Is not a date." & Chr(13)
    
    ElseIf cdate(vEffectiveDate) <= cdate(vLastRunDate) Then
        vMsg = vMsg & "[Effective Date] cannot be on/before " & vLastRunDate &"." & Chr(13)
    End IF

End If

//////////////////////////////////////////////////////////////////////////////
If UCASE(sStatus) <> "SUCCESFUL" Then
    sResponse = MsgBox ("Forecast calculation still busy. Results might not be accurate. Continue?", (vbYesNo), "WARNING")
    If sResponse = vbNo Then
        MsgBox cstr("Screen will refresh. Please click on Update to try again."), (vbOKOnly), "INFORMATION"
        ScreenForm("smoke.Calc Status").Value = "REFRESH"
        'msErr = "ABORT"
    End If
End If
//////////////////////////////////////////////////////////////////////////////

If vMsg <> "" Then
MsgBox (vMsg)
msErr = "ERROR"
End If

Hier ist das Javascript, der wichtige Teil ist zwischen dem //:

 var vEffectiveDate="";
var vLastRunDate="";
var sStatus="";
var vMsg="";
var sResponse="";
vEffectiveDate = document.getElementById("Smoke.Effective Date").value;
vLastRunDate = document.getElementById("Smoke.Last Run Date").value;
sStatus  = document.getElementById("Smoke.Calc Status").value;
vMsg = "";
if ((sStatus).length == 0  ){
    sStatus = "SUCCESFUL";
    document.getElementById("Smoke.Calc Status").value= sStatus;
}
if ((vEffectiveDate).length > 0  ){
    if (!isDate(vEffectiveDate)  ){
        vMsg = vMsg+"[Effective Date] Is not a date." + ";\r\n";
    } else if (  moment( toDate(vEffectiveDate)).isBefore(toDate(vLastRunDate)) ){
        vMsg = vMsg+"[Effective Date] cannot be on/before "+vLastRunDate+"." + ";\r\n";
    }
}
///////////////////////////////////////////////////////////
if ((sStatus).toUpperCase() != "SUCCESFUL"  ){
 $.confirm({title: "Confirmation",columnClass: 'col-md-6 col-md-offset-3', content:"Forecast calculation still busy. Results might not be accurate. Continue?", buttons: {confirm: function() { sResponse= 1;}, cancel: function() {sResponse= 2;return;}}}); if (sResponse == 2 ){ $.alert({title:  "INFORMATION",columnClass: 'col-md-6 col-md-offset-3', content:("Screen will refresh. Please click on Update to try again.").toString(),});
        document.getElementById("Smoke.Calc Status").value= "REFRESH";
  msErr = "ABORT";
    }   
}
//////////////////////////////////////////////////////////


if (vMsg != ""  ){
$.alert({title: 'Validation Message',columnClass: 'col-md-6 col-md-offset-3', content:(vMsg),});
msErr = "ERROR";
}

Ich habe gesehen, dass es in Javascript ein Konzept für asynchrone Warteversprechen gibt, aber es scheint, dass es von Internet Explorer nicht unterstützt wird , und wir müssen bedenken, dass einige unserer Benutzer tatsächlich noch IE verwenden ... seufz ... Es scheint also, dass ich kein asynchrones Konzept verwenden kann, nicht dass ich mir sicher bin, dass es in dieser Situation notwendig wäre.

Dann habe ich hier auch über eine Schaltfläche zum Senden eines Formulars gelesen , und das könnte auch mein Problem sein?

Ich habe keine Ahnung von Javascript, ich weiß nicht einmal, wie ich das Standardverhalten der Schaltfläche ändern soll, wenn dies das Problem ist.

Ich würde mich über jemanden freuen, der mir in die richtige Richtung hilft, damit ich lernen und wachsen kann.

Antworten

1 trincot Oct 09 2020 at 19:58

In der Tat wird der zweite Teil des Codes (mit der Warnung) unabhängig vom Ergebnis der Bestätigungsaufforderung ausgeführt.

Der Hauptunterschied zu $.confirmund VBAs MsgBoxbesteht darin, dass MsgBoxdie weitere Ausführung von Code blockiert wird, dies $.confirmjedoch nicht. Das bedeutet, dass der darauf folgende Code (das if (sResponse == 2)Teil) sofort ausgeführt wird. Zu diesem Zeitpunkt wurde keine Änderung vorgenommen sResponse(da keine Schaltfläche angeklickt wurde), sodass dies zu früh kommt.

Allerdings $.confirmübernimmt einige Funktionen als Argumente, die aufgerufen werden, wenn eine Taste auf dem Popup gedrückt wird. Eigentlich besteht Ihr Code solche Funktionen bereits, aber sie tun nichts anderes als das Einstellen sResult. Sie sollten also den zweiten Teil des Codes (mit der Warnung) in einer solchen Funktion verschieben.

Lassen Sie uns zuerst Ihren Code ein wenig formatieren, damit er besser lesbar wird und Sie diese Rückruffunktionen besser erkennen können:

if ((sStatus).toUpperCase() != "SUCCESFUL") {
    $.confirm({
        title:  "Confirmation",
        columnClass: 'col-md-6 col-md-offset-3', 
        content:"Forecast calculation still busy. Results might not be accurate. Continue?",
        buttons: {
            confirm: function() {
                // This executes when button is clicked
                sResponse= 1;
            },
            cancel: function() {
                // This executes when button is clicked
                sResponse= 2;
                return;
            }
        }
    });
    // This executes immediately (without waiting for button click)
    if (sResponse == 2  ){
        $.alert({ title: "INFORMATION", columnClass: 'col-md-6 col-md-offset-3', content:("Screen will refresh. Please click on Update to try again.").toString(), }); document.getElementById("Smoke.Calc Status").value= "REFRESH"; msErr = "ABORT"; } } // Also this executes too early when confirm was executed: if (vMsg != ""){ $.alert({
        title: 'Validation Message',
        columnClass: 'col-md-6 col-md-offset-3',    
        content:(vMsg),
    });
    msErr = "ERROR";
}

Ich habe Kommentare hinzugefügt, um zu zeigen, wo sich die wichtigen Teile des Codes befinden.

Verschieben Sie nun den zweiten Teil innerhalb der Rückruffunktion, die sich auf Antwort 2 bezieht:

if (sStatus.toUpperCase() != "SUCCESFUL") {
    $.confirm({ title: "Confirmation", columnClass: 'col-md-6 col-md-offset-3', content:"Forecast calculation still busy. Results might not be accurate. Continue?", buttons: { confirm: function() { sResponse= 1; processMessage(); // <--- added this }, cancel: function() { sResponse= 2; // Moved code here, as it needs to execute when Cancel is clicked $.alert({
                    title: "INFORMATION",
                    columnClass: 'col-md-6 col-md-offset-3',
                    content: "Screen will refresh. Please click on Update to try again.",
                    // Code that should execute when alert is closed:
                    onAction: function () {
                        document.getElementById("Smoke.Calc Status").value= "REFRESH";
                        msErr = "ABORT";
                        processMessage(); // <--- added this
                    }
                });
            },
        }
    });
} else { // <-- added
    processMessage();
}

function processMessage() {
    // Moved code in a function, as it should only execute after confirm/alert is closed 
    if (vMsg != "") {
        $.alert({
            title: 'Validation Message',
            columnClass: 'col-md-6 col-md-offset-3',    
            content: vMsg,
        });
        msErr = "ERROR";
    }
}

Ich habe diesen Code nicht getestet, da er Abhängigkeiten aufweist, die ich nicht kenne.