jquery - jquery promise 的延迟

标签 jquery promise jquery-deferred

我找不到 jQuery Promise 的 delaywait 函数。我在 SO ( Using jQuery.Deferred to avoid nested setTimeout callbacks ) 上找到了一个函数:

function delay(time) {
    return function () {
        console.log("Delaying");
        var ret = new $.Deferred();
        setTimeout(function () {
            ret.resolve();
        }, time);
        return ret;
    };
}

而且,这就是我使用它的方式:

 run: function () {
        return $()
            .promise()
            .then(function () {
                console.log("call together");
                console.log("call together");    
            })
            .then(delay(2000))
            .then(function () {
                console.log("call first");
            })
            .then(delay(2000))
            .then(function () {
                console.log("call second");
            })
    }

我想扩展 promise 或延迟对象,我可以这样写:

run: function () {
            return $()
                .promise()
                .then(function () {
                    console.log("call together");
                    console.log("call together");    
                })
                .delay(2000)
                .then(function () {
                    console.log("call first");
                })
                .delay(2000)
                .then(function () {
                    console.log("call second");
                })
        }

最佳答案

正如 @Bergi 所说,jQuery Deferreds/Promises 不能通过原型(prototype)继承进行扩展。

相反,jQuery 采用的模型是允许使用以下语法扩展单个 Promise 实例:

deferred.promise(target);
//or, 
promise.promise(target); //(though the documentation doesn't make this clear)
// where `target` is an "object onto which the promise methods have to be attached"
// see https://api.jquery.com/deferred.promise/

通过使用一堆方法定义构造函数,任何 jQuery Deferred 或 Promise 都可以使用简单的语法进行扩展

.promise(Constructor())

在我未发布、未记录的 jQuery Promise Playground 中,构造函数名为 $P并保存在 jQuery 命名空间中,因此我使用的实际语法是:

.promise($.$P())

您需要注意的是,在大多数情况下,没有必要调用 $.$P()明确地,因为 Playground 包含 $.when_()返回已扩展 Promise 的方法。

这是 Playground 的缩写版本,仅足以提供 .delay()方法:

(function($) {
    /* ***********************************
     * The $.$P function returns an object
     * designed to be extended with 
     * promise methods using the syntax :
     *    myDeferred.promise($.$P())
     *    myPromise.promise($.$P())
     * where `myDeferred`/`myPromise` 
     * are jQuery Deferred/Promise objects.
     * ***********************************/

    /* ***********************************
     * Methods
     * ***********************************/
    $.$P = function() {
        if (this instanceof $.$P) {
            return this;
        } else {
            return new $.$P();
        }
    };
    $.$P.prototype.then_ = function(fa, fb) {
        /* A promise method that is the same as .then()
         * but makes these extra methods available 
         * down-chain.
         */
        return this.then(fa||null, fb||null).promise($.$P());
    }
    $.$P.prototype.delay_ = function(ms) {
        /* A promise method that 
         * introduces a down-chain delay.
         */
        var promise = this;
        function f(method) {
            return function() { setTimeout(function(){ method.apply(null,this); }.bind(arguments), ms||0); };
        }
        return $.Deferred(function(dfrd) { 
            promise.then(f(dfrd.resolve), f(dfrd.reject));
        }).promise($.$P());
    }

    /* ***********************************
     * Utility functions
     * ***********************************/
    function consolidate(args) {
        /* Convert mixed promises/arrays_of_promises to single array.
         * Called by all the when_() methods below.
         */
        return Array.prototype.slice.apply(args).reduce(function(arr, current) {
            return arr.concat(current);
        }, []);
    }

    /* ***********************************
     * This section extends the jQuery namespace 
     * with a "jQuery.when_()" method.
     * ***********************************
     */
    $.extend({
        'when_': function() {
            return $.when.apply(null, consolidate(arguments)).promise($.$P()).then_(function() {
                return consolidate(arguments);
            });
        },
    });
})(jQuery);

完整的 Playground 还包括一大堆用于其他目的的静态方法和 promise 实例方法,开发它们是游戏的精髓。

使用 Playground 的基本规则如下:

  • 所有 Playground 的静态方法和 Promise 方法都以下划线“_”结尾。
  • 静态方法,例如$.when_() ,只需安装 Playgound 即可使用。
  • promise 链中的 promise 通过包含静态方法来扩展,例如 .when_() ,或链接 .promise($.$P()) .
  • 在 promise 链中,通过使用“..._”方法而不是标准方法,扩展保持可用(沿着链),例如 .then_()代替.then()

以下是如何使用它来施加问题所需的延迟:

jQuery(function($) {
    var MYNAMESPACE = {
        run: function (t) {
            return $.when_()
            .then_(function () {
                log("call together");
                log("call together");    
            })
            .delay_(t)
            .then_(function () {
                log("call first");
            })
            .delay_(t)
            .then_(function () {
                log("call second");
            });
        }
    }
});

<强> DEMO

在演示中,按钮的单击处理程序进一步指示如何使用 Playground。

使用 Playground 的规定:

  • 正如我所说 - 这是一个 Playground
  • 作为 jQuery 的适配器,而不是补丁,它在某些地方效率非常低。最糟糕的方面是,某些方法除了返回的 promise 之外还创建了中间 promise 。
  • 未按照生产代码中使用所需的标准进行测试,因此请谨慎使用。

最后,如果您决定使用 jQuery 实现延迟,则仅考虑上述内容。使用已经有 .delay() 的 Promise 库要简单得多。方法。

关于jquery - jquery promise 的延迟,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30746979/

相关文章:

java - 当我完成更改时,JQuery 对话框会自动更新表中的数据

javascript - JQuery 触发器不适用于生成的元素

javascript - 如何使用ajax响应在jquery中打印json数组

javascript - 在我的 Nodejs Controller 中 promise 不会互相等待

javascript - 按顺序排列的多个 jQuery promise

javascript - 扩展 jQuery 的 Promise 对象中的 did()

javascript - 仅对单击的按钮的 div 进行动画处理

javascript - React.js - 类型错误 : Cannot read property 'catch' of undefined

javascript - 将流的每个项目映射到 Promise 并返回其值

javascript - 延迟解析始终在 try catch 内