当前位置:  开发笔记 > 编程语言 > 正文

你能等待javascript回调吗?

如何解决《你能等待javascript回调吗?》经验,为你挑选了4个好方法。

我正在尝试使用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执行之前,有关如何正确使用回调来获取结果的任何想法?

谢谢.



1> Vincent Robe..:

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


语言的限制是不能在停留在相同的上下文中时对浏览器产生影响.如果这是可能的,我们可以写"doAjax(); while(!ajaxDone()){Sleep();}".但这在Javascript中是不可能的,因为没有睡眠或类似功能......
异步和过程模型的出色概念化。通常很多人都将两者混合在一起,而没有意识到如何解决只需要使用一个就可以解决的问题,就像我阅读此答案之前的情况一样;)

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

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

    jConfirm被调用,接收函数作为其参数之一,它记住它.

    jConfirm在页面上显示其UI并立即返回.

    'if(response == true)'行执行.真的,这应该只是读'if(response)',布尔比较是多余的.但无论如何,回应当然是错误的.您的功能放弃并退出,将控制权交还给浏览器.

    用户单击jConfirm的UI.

    j确认现在只是跳转到行动并回调你给它的功能,并且它早先记得.

    您的嵌套函数将响应设置为true,对于'if(response == true)'条件来说,它对它做任何事情都为时已晚.

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

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



3> Jonathan Lon..:

由于回调是异步的(至少在它等待用户做某事的意义上),在回调中处理你需要的内容可能更容易:

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





无限循环不起作用.JavaScript是单线程的; 当while循环旋转时,jQuery的确认UI甚至无法与之交互.

4> Ates Goral..:

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

看一下基于Narcissus的Narrative JavaScript.

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

Selenium使用这种技术.


更新

查看JavaScript链:

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

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

推荐阅读
coco2冰冰
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有