【问题标题】:JQuery - pause before executing a functionJQuery - 在执行函数之前暂停
【发布时间】:2016-12-19 14:03:19
【问题描述】:

我不能让JQuery 在函数执行前等待一秒钟。当user 打开网页时,JQuery 脚本会显示通知。目前,所有通知都会立即显示,但我希望它们在例如 1000 毫秒后被一一添加。

我尝试了setIntervalsetTimeOut,但没有任何效果。

我的代码 - 通知仍在同时显示。

function showLobiboxNotification(msg, onClickUrl) {
    Lobibox.notify('info', {
        title: 'Notification',
        delay: false,
        msg: msg,
        sound: false,
        position: 'left bottom',
        showClass: 'fadeInDown',
        hideClass: 'fadeUpDown',
        rounded: 'true',
        onClickUrl: onClickUrl
    });
    setTimeout('showLobiboxNotification', 1000)
}

$(document).ready(function () {
    $.ajax({
        type: 'GET',
        url: "/ajax/get-base-notifications/",
        success: function (data) {
            $.each(data, function (k, message) {
                setTimeout(showLobiboxNotification(message['msg'], message['url']),1000);
            });
        }
    });
});

你有什么想法吗?

【问题讨论】:

  • 这闻起来像XY question。为什么要暂停?您(尝试)在超时内创建超时,这将非常奇怪。
  • 您是否尝试过触发自定义事件并捕获它们? (参见触发方法)请记住,setTimeout 并不意味着“等待”,它只是在一秒钟后将函数调用添加到事件循环中。
  • AJAX 返回如下内容: {'message1':{'msg':'This is a message','url':'Some url'}, 'message2':{'msg' .....对于每个消息1,消息2...我调用上面的函数来创建一个通知。我想要的是在通知之间设置一些延迟。
  • 或者你可以简单地使用:showAfterPrevious: true

标签: javascript jquery


【解决方案1】:

您需要将一个函数传递给setTimeout。您正在立即调用该函数并传递结果。

    $.each(data, function (k, message) {
        setTimeout(function() {
            showLobiboxNotification(message['msg'], message['url'])
        },1000);
    });

另外,这条线毫无意义。

setTimeout('showLobiboxNotification', 1000);

如果setTimeout 的参数是字符串,则它必须是有效的Javascript 语句。仅仅给出一个函数的名字并没有任何作用。

【讨论】:

  • setTimeout(function() { showLobiboxNotification(message['msg'], message['url']) },1000); 这是在一个函数中包装一个函数 - 不是真的必要。 setTimeout(showLobiboxNotification(message['msg'], message['url']),1000); 也可以。
  • 不,它不会,这就是整个问题。调用showLobiboxNotification之前调用setTimeout
  • 不,绝对不会。你试过了吗?简单示例:var myVar; function myFunction() { myVar = setTimeout(alertFunc, 3000); } function alertFunc() { alert("Hello!"); } myFunction(); 3 秒后会显示警告框。它明确设置了一个超时,alertFunc() 在 3 秒后执行。它只是一个命名函数而不是匿名函数,这是唯一的区别。
  • 那不一样,你没有写alertFunc(),所以它传递一个对函数的引用而不是调用它。
  • 尝试setTimeout(alertFunc(), 3000) 看看与他所写内容类似的内容。
【解决方案2】:

对于每个通知,您在同一时间调用方法 showLobiboxNotification。

我认为你可以这样做

    function showLobiboxNotification(msg, onClickUrl) {
    Lobibox.notify('info', {
        title: 'Notification',
        delay: false,
        msg: msg,
        sound: false,
        position: 'left bottom',
        showClass: 'fadeInDown',
        hideClass: 'fadeUpDown',
        rounded: 'true',
        onClickUrl: onClickUrl
    });
}

$(document).ready(function () {
    $.ajax({
        type: 'GET',
        url: "/ajax/get-base-notifications/",
        success: function (data) {
            var responseIndex = 1;
            $.each(data, function (k, message) {
                setTimeout(showLobiboxNotification(message['msg'], message['url']), responseIndex * 1000);
                responseIndex++;
            });
        }
    });
});

【讨论】:

    【解决方案3】:

    我可以看到您来自同步语言,超时在 javascript 中是异步的,因此您不能在函数末尾附加超时或 sleep 并期望执行冻结,因为 javascript 不会这样做。

    用超时包装整个showLobiboxNotification 函数。这种方式比用超时包装函数的调用更模块化。并且不那么复杂。

    function showLobiboxNotification(msg, onClickUrl, delay) {
        setTimeout(function() {
    
          Lobibox.notify('info', {
            title: 'Notification',
            delay: false,
            msg: msg,
            sound: false,
            position: 'left bottom',
            showClass: 'fadeInDown',
            hideClass: 'fadeUpDown',
            rounded: 'true',
            onClickUrl: onClickUrl
          });
        }, 1000*delay)
    }
    
    $(document).ready(function () {
        $.ajax({
            type: 'GET',
            url: "/ajax/get-base-notifications/",
            success: function (data) {
                $.each(data, function (k, message) {
                    showLobiboxNotification(message['msg'], message['url'], k);
                });
            }
        });
    });
    

    另外,如果你是函数式编程的粉丝,你可以编写一个帮助程序

    callAfterDelay(delay, fn, params,) {
        setTimeout(function() {
           fn(...params)
        }, 1000*delay)
    }
    
    $(document).ready(function () {
        $.ajax({
            type: 'GET',
            url: "/ajax/get-base-notifications/",
            success: function (data) {
                $.each(data, function (k, message) {
                    callAfterDelay(k, showLobiboxNotification, [message['msg'], message['url']];
                });
            }
        });
    });
    

    【讨论】:

    • 如果有 10 个通知,这只会在 1 秒的时间内设置 10 个超时,但同时设置这些超时,因此它们仍然会同时发生(或足够接近)。当然不是间隔 1 秒。
    • 只是添加了延迟,OP的问题是他面临异步和同步的问题,而不是代码编写。正如我在答案开头所说的那样,它是异步的,而他认为它是同步的。反正
    • 他已经有延迟了,你只是移动到了延迟代码写的地方。问题是他希望他们在通知之间等待一秒钟,而不是在 ajax 返回后等待一秒钟。
    • 好的,刚刚发现了 1000*delay - 抱歉,今天下午没有正确阅读!好的,它可能会工作。
    猜你喜欢
    • 1970-01-01
    • 2010-11-15
    • 1970-01-01
    • 2021-05-01
    • 1970-01-01
    • 2011-09-22
    • 1970-01-01
    • 1970-01-01
    • 2012-03-26
    相关资源
    最近更新 更多