你能等待javascript回调吗?

我正在尝试使用http://abeautifulsite.net/notebook/87中的jQuery警报对话库而不是默认警报(在我看来这看起来非常糟糕)。 这似乎是一个很棒的库,但是没有一个如何使用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按钮的来电:

我在插件的网站上发布了一条评论(就在今天早上),谷歌搜索了javascript并等待回调完成但没有结果。

在其余的javascript执行之前,有关如何正确使用回调来获取结果的任何想法?

谢谢。

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

这背叛了对使用异步代码发生的事件序列的误解。 仅仅因为你把它写成内联并不意味着它将严格执行从上到下的执行。

  1. jConfirm被调用,接收函数作为其参数之一,它记得它。
  2. jConfirm在页面上显示其UI并立即返回。
  3. ‘if(response == true)’行执行。 真的,这应该只是读’if(response)’,布尔比较是多余的。 但无论如何,回应当然是错误的。 您的function放弃并退出,将控制权交还给浏览器。
  4. 用户单击jConfirm的UI。
  5. j现在只确认跳转到操作并回调你给它的function,并且它早些时候记得。
  6. 您的嵌套函数将响应设置为true,对于’if(response == true)’条件来说,使用它做任何事情都为时已晚。

您已经写了“//等待响应”作为替代方案,但是没有可以编写的JavaScript代码实际上会这样做。 在浏览器触发jConfirm UI上的单击事件以使处理继续之前,您的函数必须返回以将控制权交还给浏览器。

存在使异步代码在同步上下文中工作(反之亦然)的方法 – 特别是线程和协同程序(以及它们有限的关系生成器)。 但JavaScript没有这些function,因此您必须编写代码以适应库所使用的同步或异步模型。

你刚刚在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()和prompt()相同的值。 您必须使用回调函数访问结果值。 (有关详细信息,请参阅演示。)


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

从技术上讲, 是的 ,但我不会在网站上这样做。

看一下基于Narcissus的 Narrative JavaScript 。

叙事JavaScript是JavaScript语言的一个小扩展,它支持异步事件回调的阻塞function。 这使得异步代码清晰可读且易于理解。

Selenium使用这项技术。


更新

查看JavaScript链 :

JavaScript Strands为JavaScript语言添加了协程和协作线程支持,以支持异步事件回调的阻塞function。 这使得利用异步操作的代码更加线性,可读和可管理。 Strands建立在Neil Mix编写的Narrative JavaScript之上,很多Narrative JavaScript都保留在Strands中,其中包括大部分文档。

在JavaScript中,您的代码不能简单地等到事件被触发 – 事件必须始终由单独的异步事件处理程序处理。 有时这很好,但它往往会迫使一些简单的陈述序列变成粗糙的扭曲。 它还打破了封装function的能力,因为调用函数必须知道提供回调处理程序。 Strands提供了暂停和恢复执行线程的能力。 执行可以在事件结束时暂停恢复。 这允许您在简单,线性,可读的代码中编写难以读取的异步事件处理,这些代码封装了实现。

我想你必须抓住这样的回应。 我认为你不需要回调。

 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:

我们可以做类似的事情:

  

和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('

' + msg + '

').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('
'+ '

Kinnitus

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