Можете ли вы дождаться обратного вызова javascript?

Я пытаюсь использовать библиотеку диалоговых окон jQuery alerts изhttp://abeautifulsite.net/notebook/87 вместо предупреждений по умолчанию (которые выглядят довольно ужасно, на мой взгляд). Это кажется отличной библиотекой, но нет примера того, как использовать библиотеку jConfirm.

Мне нужно сделать что-то вроде этого:

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');
        }
    }

и мой звонок с моей кнопки .net:

я опубликовал комментарий на веб-сайте плагина (только сегодня утром) и сделал Google ищет javascript и ждет обратного вызова для завершения без каких-либо результатов.

любые идеи о том, как правильно использовать обратный вызов, чтобы получить результат, до выполнения остальной части javascript?

спасибо.

9 ответов


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

это выдает неправильное понимание последовательности событий, происходящих с использованием асинхронного кода. Только потому, что вы написали его встроенным, не означает, что он будет выполняться строго сверху вниз.

  1. jconfirm вызывается, получая функцию как один из ее параметров, который она запоминает.
  2. jConfirm отображает свой пользовательский интерфейс на странице и немедленно возвращается.
  3. выполняется строка " if (response==true)". На самом деле это должно просто читать " если (response)', логическое сравнение излишне. Но в любом случае ответ, конечно, ложен. Ваша функция сдается и выходит, возвращая управление браузеру.
  4. пользователь нажимает пользовательский интерфейс jConfirm.
  5. jConfirm только теперь переходит в действие и вызывает функцию, которую вы ей дали, и она вспомнила ранее.
  6. ваша вложенная функция устанавливает ответ true, слишком поздно для условия " if (response==true)", чтобы что-либо с ним сделать.

вы в качестве альтернативы написали "//wait for response", но нет кода JavaScript, который вы можете написать, который действительно это сделает. Ваша функция должна вернуться, чтобы вернуть управление браузеру, прежде чем браузер сможет запустить события click в пользовательском интерфейсе jConfirm, которые заставляют обработку продолжаться.

существуют способы заставить асинхронный код работать в синхронном контексте (и наоборот) - в частности, потоки и сопрограммы (и их генераторы ограниченных отношений). Но JavaScript не имеет ни одного из этих функции, поэтому вы должны написать свой код, чтобы соответствовать синхронной или асинхронной модели, используемой вашей библиотекой.


вы только что попали в большое ограничение в JavaScript. Как только ваш код попадает в асинхронный мир, нет способа вернуться к классическому процессуальному потоку выполнения.

в вашем примере решением было бы сделать цикл, ожидающий заполнения ответа. Проблема в том, что JavaScript не предоставляет никаких инструкций, которые позволят вам бесконечно петлять, не принимая 100% вычислительной мощности. Таким образом, вы в конечном итоге блокируете браузер, иногда до точки где ваш пользователь не сможет ответить на актуальный вопрос.

единственное решение здесь-придерживаться асинхронной модели и сохранить ее. Мой совет заключается в том, что вы должны добавить обратный вызов к любой функции, которая должна выполнять некоторую асинхронную работу, чтобы вызывающий мог выполнить что-то в конце вашей функции.

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');
})

поскольку обратный вызов асинхронен (по крайней мере, в том смысле, что он ждет, когда пользователь что-то сделает), может быть проще обрабатывать то, что вам нужно внутри обратного вызова:

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

@klogan [комментарии]

Я предполагаю, что вы получили их от здесь?

страница дает вам ответ: (посмотрите под использование)

эти методы не возвращают те же значения, что и confirm () и проворный.)( Вы должны получить доступ к результирующим значениям с помощью функции обратного вызова. (См. демо для получения более подробной информации.)


@klogan

Я пытаюсь сказать, что на самом деле нет простого способа выполнить то, что вы хотите. Вы пытаетесь соотнести процедурные и событийная Программирование -- что-то JavaScript не помогает вам делать.

Самый простой (хотя, рискованные) решение заключается в использовании псевдо-бесконечного цикла. Но если ... --2--> никогда не вызывается, теперь у вас есть фактически бесконечный цикл. И, в зависимости от движка JavaScript, вы можете убить ожидание браузера.

точка: ваш лучший выбор, чтобы избежать этой попытка принудить события, управляемые процедурными.

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;
}


технически да, но я бы не сделал этого на веб-сайте.

посмотри Повествовательный JavaScript, который Нарцисс.

Narrative JavaScript-это небольшое расширение языка JavaScript, которое позволяет блокировать возможности асинхронных обратных вызовов событий. Это делает асинхронный код освежающе читаемым и понятным.

селен использует этот технология.


обновление

проверить JavaScript Strands:

JavaScript Strands добавляет корутин и поддержка кооперативных потоков в Язык JavaScript для включения блокировки возможности для асинхронного события обратный вызов. Это делает код, который использует асинхронную деятельность много более линейный, читаемый и управляемый. Strands построен на повествовании JavaScript, написанный Neil Mix, и значительная часть Повествование в JavaScript остался в прядях, включая большую часть эта документация.

в JavaScript ваш код не может просто подождите, пока не произойдет событие ... событие всегда должно обрабатываться отдельный асинхронный обработчик событий. Иногда это хорошо, но это часто силы, которые должны быть простыми последовательность утверждений в gnarly искажения. Он также ломает возможность инкапсуляции функциональности потому что вызывающие функции должны знать обеспечить обработчик обратного вызова. Стружка предоставляет возможность приостановить и возобновление потоков выполнения. Исполнение может приостановить возобновление, когда событие законченный. Это позволяет вам писать трудночитаемое асинхронное событие обработка в простой, линейный, читаемый код, инкапсулирующий реализацию.


Я бы предположил, что вам придется схватить ответ Вот так. Не думаю, что тебе нужно перезванивать.

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

Я думаю, что я придумал возможное решение этой проблемы. Я читал эту статью: http://treasure4developer.wordpress.com/2008/06/23/calling-postback-event-from-javascript/

в основном идея заключается в том, что вы заставляете обратную передачу из javascript, сначала я обнаружил, что обратная передача будет работать, но не будет вызывать мое событие кнопки, но после прочтения статьи я обнаружил, что могу определить, была ли это обратная передача javascript и просто вызвать метод для выполнения обработка

С Уважением DotnetShadow


как чуваки сказали, нет никакого способа! но... как мы говорим в моей стране (Бразилия), le gambi:

мы можем сделать что-то вроде этого:

<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}"/>

и 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;
}

это та же проблема, но с использованием jQuery-ui.

bye и я надеюсь, что это может помочь кому-то.


подумайте о обратных вызовах как отправке сообщений, и это приведет к лучшей структуре в вашем коде.


эта штука работает. Нуждается в 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;
}