延迟jquery承诺 [英] delay for jquery promises

查看:68
本文介绍了延迟jquery承诺的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我找不到延迟等待函数 jQuery 承诺。我在SO上找到了一个函数(使用jQuery.Deferred以避免嵌套的setTimeout回调):

I cannot find delay or wait function for jQuery promises. I have found one function on the 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;
    };
}

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

And, it's the way how I use it:

 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或deferred对象:

I want to extend promise or deferred object that I can write like:

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不是可以通过原型继承扩展。

As @Bergi says jQuery Deferreds/Promises are not extendible by prototypal inheritance.

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

Instead, the model adopted by jQuery is to allow individual Promise instances to be extended with the syntax :

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延迟或者Promise可以使用简单的语法扩展

By defining a constructor with a bunch of methods, any jQuery Deferred or Promise can be extended with the simple syntax

.promise(Constructor())

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

In my unpublished, undocumented jQuery promises Playground, the constructor is named $P and kept in the jQuery namespace, hence the actual syntax I use is :

.promise($.$P())

你需要注意的是,在大多数情况下,没有必要调用 $ 。$ P()显式为Playground包含 $。当_()方法返回已经扩展的Promise。

You need to be aware of that, for the most part, it's not necessary to call $.$P() explicitly as the Playground includes a $.when_() method that returns an already extended Promise.

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

Here's an abbreviated version of the Playground with just enough to provide a .delay() method :

(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-instance方法用于其他目的,开发它们是该剧的精髓。

使用Playgound的基本规则如下:

The ground-rules for using the Playgound are as follows :


  • 所有Playground的静态和promise方法都以_下划线结尾。

  • 静态方法,例如 $。当_(),只需安装Playgound即可使用。

  • 承诺链中的承诺通过包含静态方法来扩展,例如 .when _(),或链接 .promise($。$ P())

  • 在承诺链中,通过使用..._方法而不是标准,扩展仍然可用(在链中)方法,例如 .then _()代替 .then()

  • All the Playground's static and promise methods end in "_" underscore.
  • Static methods, eg $.when_(), are made available just by installing the Playgound.
  • Promises in a promise chain are extended by including a static method, eg .when_(), or chaining .promise($.$P()).
  • In a promise chain, the extensions remain available (down the chain) by using "..._" methods rather than the standard methods, eg .then_() in place of .then().

所以这里是如何使用它来强加问题所需的延迟:

So here's how to use it to impose the delays required by the question :

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

DEMO

在演示中,按钮的点击处理程序进一步说明了如何使用Playground。

In the demo, the button's click handler gives further indication of how the Playground can be used.

使用游乐场的Provisos:

Provisos on using the Playground :


  • 正如我所说 - 这是一个游乐场

  • 作为jQuery的适配器,而不是补丁,它在某些地方效率极低。最糟糕的是,除了返回的方法之外,某些方法还会产生中间承诺。

  • 未按生产代码中使用的标准进行测试,因此请谨慎使用。

最后,如果你决定用jQuery实现延迟,只考虑上面的内容。使用已经有 .delay()方法的promise lib要简单得多。

And lastly, only consider the above if you are determined to implement delay with jQuery. It's far far simpler to use a promise lib that already has a .delay() method.

这篇关于延迟jquery承诺的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆