在没有Promise或任何JS库的情况下延迟函数执行

时间:2017-03-23 04:21:43

标签: javascript deferred deferred-execution

我正在开发一个将公开3种方法的库。所有这三种方法都依赖于另一个已加载的库(称为libA),并且该库是异步加载的。

一旦JS文件加载完毕,我就可以编写代码来公开方法,但是用户必须推迟执行直到libA完成。

我希望,而不是揭露"一个版本"当libA继续在后台异步加载时,立即使用这3种方法。任何对这3种方法的调用都会排队,直到libA完成加载。在libA完成加载后,这三个方法将被替换为真实方法,并且队列将被处理。

我们说我有这个:

var myLib = (function(){
    // expose 3 functions for the user to use
    return {
        "func1" : function(opts){},
        "func2" : function(opts){},
        "func3" : function(opts){}
    }
})();

该库将由用户加载。同时也会加载libA。可能需要更长时间才能装载,或者可能在我开始之前完成。

因此,如果用户运行myLib.func1({})并且libA尚未完成加载,那么它应该排队,然后当libA完成时它应该执行。另一方面,如果libA已完成加载,则会立即执行。

我最初的想法是做这样的事情:

var myLib = (function(){
    // queue the calls
    var queue {
        "func1" : [],
        "func2" : [],
        "func3" : []
    };

    // the "temp" functions that just add them to the queue
    var ret = {
        "func1" : function(opts){ queue.func1.push(opts); },
        "func2" : function(opts){ queue.func2.push(opts); },
        "func3" : function(opts){ queue.func3.push(opts); }
    }

    // this may happen before the user users my library or after
    // if it happens before then the functions will be replaced before the user calls them and they won't need to be queued
    // if it happens after then the functions will get replaced and the queued up ones will be executed
    waitForLibAToFinish(function(){
        ret.funct1 = function(opts){alert("this is the real func1");},
        ret.funct2 = function(opts){alert("this is the real func2");},
        ret.funct3 = function(opts){alert("this is the real func3");},

        // process the queue
        for(var i = 0; i < queue.func1.length; ++i)
        {
            ret.func1(queue.func1[i]);
        }

        // repeat for func2 and func3 queue
    });

    return ret;
})();

但这似乎是一种糟糕的方式。另外,我必须为每个功能都有一个队列并调用每个功能。必须有一种方法来抽象出那个部分,这样我的库暴露的所有方法都更通用。

我对任何想法/建议持开放态度。我不能(由于我无法控制的众多原因)使用任何第三方库,如Promise或JavaScript。而且,我的代码必须在IE8上工作。相信我,我比你更讨厌它。

===

我添加了更多上下文/详细信息。

我知道我提到了SharePoint,但这不是特定于SP的问题。

我正在构建一个库,它提供了方便的方法来简化SharePoint中复杂的任务。我所有的库都是调用SP库。相关的SP库是异步加载的。因此,有两件事情需要发生:

  • 在调用我的库中的任何方法之前,用户需要等待相关的SP库完成加载
  • 或者我的图书馆需要等待相关的SP库完成

SP提供的功能让你排队&#34;在加载相关SP库之前,您的函数是ExecuteOrDelayUntillScriptLoaded

我的图书馆目前建立在第一个选项上。我想简化用户的体验,因此他们不必检查(通过ExecuteOrDelayUntillScriptLoaded)。我可以将它改为第二种方式,但有理由我不想。

相反,我希望做的是在我的图书馆中使用ExecuteOrDelayUntillScriptLoaded进行1次检查,以便修改&#34;我的图书馆做了什么。在完成相关库之前,加载我的库只会将调用排队。在完成加载和ExecuteOrDelayUntillScriptLoaded触发后,我的代码将:

  • 执行队列中的所有内容
  • 修改我的库公开的每个函数以直接执行而不是队列

1 个答案:

答案 0 :(得分:1)

不要自己排队。将库加载和依赖性解析保留给用户。只需公开一个实例化库的函数,用户可以在库A准备就绪时调用它,并使用可用方法返回模块。
甚至已经有了如何做到这一点的标准:Asynchronous Module Definition。 (您不需要require.js作为第三方库,您可以自己实施基本要素)

如果用户希望(需要)在加载所有内容之前调用库方法,他们总是可以以他们想要的任何方式对过早的调用进行排队。但通常这不是必要的。