Вы можете дождаться обратного вызова javascript?

Я пытаюсь использовать библиотеку диалоговых окон предупреждений jQuery из 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?

Спасибо.

Обновление: посетите сайт авторов. Он оставил комментарий, что на самом деле он не предназначен для того, чтобы он работал так, как я хотел. Ответы на этот пост тоже подтверждают это. Спасибо всем!!

AlignedDev 06.02.2009 18:58

Там есть плагин: stackoverflow.com/questions/6457750/form-confirm-before-subm‌ это /…

user1662811 11.09.2012 16:16
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
22
2
69 294
9
Перейти к ответу Данный вопрос помечен как решенный

Ответы 9

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

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

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

AlignedDev 12.01.2009 22:46

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

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

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

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

Эта страница дает вам ваш ответ: (смотрите под Применение)

These methods do not return the same values as confirm() and prompt(). You must access the resulting values using a callback function. (See the demo for more details.)


@klogan

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

Самое простое (хотя и рискованный) решение - использовать псевдобесконечный цикл. Но если callback никогда не вызывается, теперь у вас фактически бесконечный цикл. И, в зависимости от движка 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;
}

Спасибо за ответ, но мне нужна функция, возвращающая результат функции обратного вызова. Поэтому, если пользователь нажимает ОК -> вернуть истину, если пользователь нажимает отменить -> вернуть ложь. Тогда это будет работать так же, как встроенная функция подтверждения.

AlignedDev 12.01.2009 22:51

Я получил ответ с их веб-страницы.

AlignedDev 12.01.2009 22:59

и их демонстрационный код не показывает, как использовать результаты подтверждения

AlignedDev 12.01.2009 23:18

Спасибо, я действительно попробовал цикл while, чтобы проверить это решение, но IE выдаст диалоговое окно с предупреждением о зависании javascript. Вы правы, я бы не хотел этого делать. Я буду ждать ответа от авторов и опубликую решение. Может, они сами не доделали.

AlignedDev 13.01.2009 00:09

Бесконечный цикл работать не будет. JavaScript однопоточный; Пользовательский интерфейс подтверждения jQuery невозможно даже взаимодействовать во время вращения цикла while.

bobince 13.01.2009 00:27

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

Взгляните на Повествовательный JavaScript, который основан на Нарцисс.

Narrative JavaScript is a small extension to the JavaScript language that enables blocking capabilities for asynchronous event callbacks. This makes asynchronous code refreshingly readable and comprehensible.

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


Обновлять

Проверьте Нити JavaScript:

JavaScript Strands adds coroutine and cooperative threading support to the JavaScript language to enable blocking capabilities for asynchronous event callbacks. This makes code that utilizes asynchronous operation much more linear, readable, and manageable. Strands is built upon Narrative JavaScript written by Neil Mix, and much of Narrative JavaScript has remained in Strands including much of this documentation.

In JavaScript your code can't simply wait until an event has fired -- the event must always be handled by a separate, asynchronous event handler. Sometimes this is fine, but it often forces what ought to be a simple sequence of statements into gnarly contortions. It also breaks the ability to encapsulate functionality because calling functions must know to provide a callback handler. Strands provides the ability to suspend and resume threads of execution. Execution can suspend resume when the event is finished. This allows you to write hard-to-read asynchronous event handling in simple, linear, readable code that encapsulates implementation.

Ваша ссылка на Javascript Strands мертва. Жаль, как это интересно звучит.

Leopd 06.09.2011 09:15
Ответ принят как подходящий
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). На самом деле это должно быть просто «if (response)», логическое сравнение излишне. Но в любом случае ответ, конечно, ложный. Ваша функция отключается и завершается, возвращая управление браузеру.
  4. Пользователь щелкает пользовательский интерфейс jConfirm.
  5. jConfirm только сейчас переходит в действие и вызывает функцию, которую вы ему дали и запомнили ранее.
  6. Ваша вложенная функция устанавливает response true, слишком поздно для условия if (response == true), чтобы что-то с ней сделать.

В качестве альтернативы вы написали «// ждем ответа», но нет кода JavaScript, который вы могли бы написать, который действительно это делал бы. Ваша функция должна вернуться, чтобы вернуть управление браузеру, прежде чем браузер сможет запускать события щелчка в пользовательском интерфейсе jConfirm, которые заставляют обработку продолжаться.

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

Это хороший ответ. Но как насчет некоторого кода о том, как структурировать обратный вызов?

Cris Stringfellow 08.03.2012 08:10

Вы только что столкнулись с большим ограничением в 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');
})

Это не ограничение в javascript. Так работают html-страницы. Ничего общего с javascript.

dkretz 16.01.2009 10:06

Это ограничение языка - не иметь возможности уступить место браузеру, оставаясь в том же контексте. Если бы это было возможно, мы могли бы написать «doAjax (); while (! AjaxDone ()) {Sleep ();}». Но в Javascript это невозможно, потому что нет Sleep или подобной функции ...

Vincent Robert 21.01.2009 20:51

БОЛЬШАЯ концептуализация асинхронной и процедурной моделей. Часто у многих есть код, который представляет собой смесь того и другого, и они не понимают, как решить проблему, требующую использования только одного, как это было со мной до того, как я прочитал этот ответ;)

Kevin 15.07.2011 00:37

@dkretz: Конечно, это ограничение Javascript (как описано; в 2019 году изменилось). Да, веб-страницы работают асинхронно для удобства пользователя. Но циклы событий - не единственный способ заниматься асинхронным программированием.

user1071847 15.05.2019 15:14

Думаю, я придумал возможное решение этой проблемы. Я читал эту статью: 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.

Пока, надеюсь, это кому-нибудь поможет.

Эта штука работает. Требуется 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;
}

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

Другие вопросы по теме