webentwicklung-frage-antwort-db.com.de

Kannst du auf Javascript Rückruf warten?

Ich versuche, die jQuery-Alarme-Dialogbibliothek von http://abeautifulsite.net/notebook/87 anstelle der Standardalarme (die meiner Meinung nach ziemlich schrecklich aussehen) zu verwenden. Dies scheint eine großartige Bibliothek zu sein, aber es gibt kein Beispiel für die Verwendung der jConfirm-Bibliothek.

Ich muss so etwas tun:

function confirm() {
        var result = false;
        var response = false;
        jConfirm('are you sure?', 'Confirmation Dialog',
          function(r) {
            result = r;
            response = true;
            return r;
        });
        if (response == true) {
            alert(result);
            return result;
        }
        else {
            //wait for response
            alert('hi');
        }
    }

und mein Anruf von meiner .net-Taste:

Ich habe einen Kommentar auf der Website des Plugins veröffentlicht (nur heute Morgen). Google hat nach Javascript gesucht und darauf gewartet, dass ein Rückruf ohne Ergebnisse abgeschlossen wird.

Irgendwelche Ideen, wie man den Rückruf korrekt verwendet, um das Ergebnis zu erhalten, bevor der Rest des Javascript ausgeführt wird?

Vielen Dank.

22
Aligned
jConfirm('are you sure?', 'Confirmation Dialog',
    function(r) {
        result = r;
        response = true;
        return r;
    }
);
if (response == true) {

Dies weist auf ein Missverständnis der Reihenfolge der Ereignisse hin, die bei Verwendung von asynchronem Code auftreten. Nur weil Sie es inline geschrieben haben, heißt das nicht, dass es strikt von oben nach unten ausgeführt wird.

  1. jConfirm wird aufgerufen und empfängt eine Funktion als einen seiner Parameter, an die es sich erinnert.
  2. jConfirm zeigt seine Benutzeroberfläche auf der Seite an und kehrt sofort zurück.
  3. Die 'if (response == true)' Zeile wird ausgeführt. Eigentlich sollte dies nur "wenn (Antwort)" lauten, der boolesche Vergleich ist überflüssig. In jedem Fall ist die Antwort natürlich falsch. Ihre Funktion gibt auf und beendet den Browser.
  4. Der Benutzer klickt auf die Benutzeroberfläche von jConfirm.
  5. jConfirm springt erst jetzt in Aktion und ruft die von Ihnen angegebene Funktion zurück, an die sie sich früher erinnert hat.
  6. Ihre verschachtelte Funktion setzt die Antwort auf true, viel zu spät, damit die Bedingung 'if (response == true)' nichts dagegen tun kann.

Sie haben als Alternative "// wait for response" geschrieben, aber es gibt keinen JavaScript-Code, den Sie schreiben können. Ihre Funktion muss zurückkehren, um die Kontrolle an den Browser zurückzugeben, bevor der Browser die Klickereignisse auf der jConfirm-Benutzeroberfläche auslösen kann, die die Verarbeitung fortsetzen.

Es gibt Möglichkeiten, um asynchronen Code in einem synchronen Kontext (und umgekehrt) zum Laufen zu bringen - insbesondere Threads und Coroutines (und ihre begrenzten Beziehungsgeneratoren). JavaScript verfügt jedoch über keine dieser Funktionen. Daher müssen Sie Ihren Code so schreiben, dass er zu dem synchronen oder asynchronen Modell passt, das Ihre Bibliothek verwendet.

16
bobince

Sie haben gerade eine große Einschränkung in JavaScript erreicht. Sobald Ihr Code in die asynchrone Welt gelangt ist, gibt es keine Möglichkeit, zu einem klassischen prozeduralen Ausführungsablauf zurückzukehren.

In Ihrem Beispiel wäre die Lösung, eine Schleife zu erstellen, die darauf wartet, dass die Antwort gefüllt wird. Das Problem ist, dass JavaScript keine Anweisungen enthält, die es Ihnen ermöglichen, eine unendliche Schleife ohne 100% der Prozessorleistung auszuführen. Am Ende blockieren Sie also den Browser, manchmal bis zu einem Punkt, an dem Ihr Benutzer die eigentliche Frage nicht beantworten kann.

Die einzige Lösung hier ist, sich an das asynchrone Modell zu halten und es zu behalten. Mein Rat ist, dass Sie einer Funktion, die asynchron arbeiten muss, einen Rückruf hinzufügen, damit der Aufrufer am Ende der Funktion etwas ausführen kann.

function confirm(fnCallback) 
{
    jConfirm('are you sure?', 'Confirmation Dialog', function(r) 
    {
        // Do something with r 

        fnCallback && fnCallback(r); // call the callback if provided
    });
}

// in the caller

alert('begin');

confirm(function(r)
{
    alert(r);

    alert('end');
})
19
Vincent Robert

Da der Rückruf asynchron ist (zumindest in dem Sinne, dass er darauf wartet, dass der Benutzer etwas tut), ist es möglicherweise einfacher, das zu erledigen, was Sie im Rückruf benötigen:

function confirm() {
    jConfirm('are you sure?', 'Confirmation Dialog', function(r) {
        if (r) doSomething();
    });
}

@klogan [Kommentare]

Ich nehme an, Sie haben diese von hier ?

Die Seite gibt Ihnen Ihre Antwort: (schauen Sie unter Usage)

Diese Methoden liefern nicht dieselben Werte wie confirm () und Prompt (). Sie müssen auf die resultierenden Werte mithilfe einer Rückruffunktion zugreifen. (Weitere Informationen finden Sie in der Demo.)


@klogan

Der Punkt, den ich zu sagen versuche, ist, dass es nicht wirklich einfach ist, das zu erreichen, was Sie wollen. Sie versuchen, die Programmierung von prozedural und ereignisgesteuert zu korrelieren - etwas, das JavaScript Ihnen nicht hilft.

Die einfachste (wenn auch riskante) - Lösung ist die Verwendung einer Pseudo-Endlos-Schleife. Wenn jedoch callback nie aufgerufen wird, haben Sie jetzt eine tatsächliche Endlosschleife. Und abhängig von der JavaScript-Engine könnten Sie den wartenden Browser beenden.</ p>

Punkt: Am besten vermeiden Sie diese Versuch ereignisgesteuert in ein Verfahren zu zwingen.

function confirm() {
    var result = false;
    var response = false;

    jConfirm('are you sure?', 'Confirmation Dialog',
      function(r) {
        result = r;
        response = true;
    });

    while(!response) continue; // wait
    return result;
}

8

Technisch gesehen ja, aber ich würde das nicht auf einer Website machen.

Werfen Sie einen Blick auf Narrative JavaScript , das auf Narcissus basiert.

Narrative JavaScript ist eine kleine Erweiterung der JavaScript-Sprache, die das Sperren von asynchronen Ereignisrückrufen ermöglicht. Dies macht asynchronen Code erfrischend lesbar und verständlich. 

Selen verwendet diese Technologie.


Aktualisieren

Check out JavaScript-Stränge :

JavaScript Strands fügt Coroutine und .__ hinzu. kooperative Threading-Unterstützung für die JavaScript-Sprache zum Aktivieren des Blockierens Fähigkeiten für asynchrone Ereignisse Rückrufe. Dadurch wird Code verwendet asynchronen Betrieb viel linearer, lesbarer und handhabbarer . Stränge bauen auf Erzählung auf JavaScript geschrieben von Neil Mix und viel von narrativem JavaScript hat blieb in Strands, darunter ein großer Teil von diese Dokumentation.

In JavaScript kann Ihr Code nicht einfach Warten Sie, bis ein Ereignis ausgelöst wurde - das Ereignis muss immer von einem .__ behandelt werden. separater, asynchroner Ereignishandler . Manchmal ist das gut, aber oft zwingt, was ein einfaches sein sollte Folge von Anweisungen in gnarly Verrenkungen. Es bricht auch die Fähigkeit, Funktionalität zu kapseln weil aufrufende Funktionen wissen müssen einen Callback-Handler bereitstellen. Stränge bietet die Möglichkeit, und .__ auszusetzen. Wiederaufnahme von Threads der Ausführung. Ausführung kann den Lebenslauf aussetzen, wenn das Ereignis .__ ist. fertig. Damit können Sie schreiben schwer lesbares asynchrones Ereignis Handhabung in einfacher, linearer, lesbarer Form Code, der die Implementierung enthält.

5
Ates Goral

Das Ding funktioniert. Benötigt jQuery.

function myconfirm(kyssa, Elm, e){ // neG
    if(jQuery('#confirmquestion').data('result')){
        var V = jQuery('#confirmquestion').data('result');
        jQuery('#confirmquestion').remove(); 
        return V == 'Y' ? true : false;         
    }else if(!jQuery('#confirmquestion').length){
        jQuery('body').append('<div id="confirmquestion">'+
        '<h4>Kinnitus</h4>'+
        '<div id="kyssa">'+kyssa+'</div>'+
        '<center>'+
        '<button onclick="jQuery(\'#confirmquestion\').data(\'result\', \'Y\');">Jah</button>&nbsp;'+
        '<button onclick="jQuery(\'#confirmquestion\').data(\'result\', \'N\');">Ei</button></div>'+
        '</center>');
        jQuery('#confirmquestion button').click(function(){
            jQuery(Elm).trigger(e.type);
        })
    }       
    return false;
}

onChange="if(myconfirm(\'Saada kiri: \'+jQuery(this).find(\'option:selected\').html()+\' ?\', this, event)) { ... }"

CSS

#confirmquestion{
    border:1px solid #999;
    background:white;
    padding-bottom: 30px;
    position:fixed;
    width:300px;
    font-size:12px;
    top:45%;
    left:50%;
    margin-left:-150px;
}

#confirmquestion h4 {
    background:blue;
    color:white;
    margin:0;
    padding: 2px 5px;
    border-bottom:#777; 
    text-align:center;
}

#confirmquestion #kyssa {
    padding: 30px 25px;
}
0
neG

Wie die Jungs sagten, gibt es keinen Weg! aber ... wie wir in meinem Land (Brasilien) sagen, le gambi:

wir können so etwas machen:

<h:commandLink styleClass="linkValor xExcluir" value="x"  
                     onclick="if(confirmar('Confirmar excluir.','Deseja realmente excluir este registro?', this)) return true; else return false;"
                     action="#{mBeanPesquisarLinhas.excluir}"/>

und das Javascript:

function confirmar(titulo, msg, elemento) { 

    if ($(elemento).attr('sim')) {      
        $(elemento).removeAttr('sim');      
        return true;
    } else if ($(elemento).attr('nao')) {       
        $(elemento).removeAttr('nao');      
        return false;
    } else {
        $("#dialog-confirm").html('<p>' + msg + '</p>').dialog({
            resizable : false,
            height : 200,
            modal : true,
            title : titulo,
            buttons : {
                "Sim" : function() {
                    $(this).dialog("close");
                    $(elemento).attr('sim', 'sim');
                    $(elemento).click();
                },
                "Não" : function() {
                    $(this).dialog("close");
                    $(elemento).attr('nao', 'nao');
                    $(elemento).click();
                }
            }
        });
    }

    return false;
}

es ist das gleiche problem, aber mit jquery-ui.

Tschüss und ich hoffe das kann jemandem helfen.

0
MaikoID

Ich würde davon ausgehen, dass Sie die Antwort so ergreifen müssten. Ich glaube nicht, dass du einen Rückruf brauchst.

function confirm() {
        var response = jConfirm('are you sure?', 'Confirmation Dialog');
        if (response) {
            alert(result);
        }
        else {
            //wait for response
            alert('hi');
        }
    }

Ich denke, ich habe eine mögliche Lösung für dieses Problem gefunden. Ich habe diesen Artikel gelesen: http://treasure4developer.wordpress.com/2008/06/23/calling-postback-event-from-javascript/

Grundsätzlich ist die Idee, dass Sie das Postback von Javascript erzwingen. Zuerst stellte ich fest, dass das Postback funktionieren würde, meinen Button jedoch nicht aufrufen würde, aber nachdem ich den Artikel gelesen hatte, stellte ich fest, dass ich feststellen konnte, ob es sich um ein Javascript-Postback handelt Methode für die Verarbeitung

Grüße DotnetShadow

0
DotnetShadow

Denken Sie an Rückrufe wie das Senden von Nachrichten. Dies führt zu einer besseren Struktur in Ihrem Code. 

0