JS获取调用函数并将其作为异步回调重新执行

时间:2017-08-31 06:58:06

标签: javascript asynchronous callback

在vanilla Javascript(ES5)中是否有办法获取调用函数并在异步调用完成后重新执行它而无需将其作为回调函数传递?

我正在系统上构建一个缓存机制,由于某种原因,我不可能使用promises,es6的生成器函数等(我认为任何现代js功能都有帮助)。

现在,我正在以这种方式编码(这是一个非常简化的版本):

var cache = {};
var cacheCallbackQueue = [];

var theCallerFunction = function(someParam){

    loadCache("aDataTarget",function(){
        theCallerFunction(someParam);
    });

    // cache will be used here somehow
    // if the needed cache haven't been loaded
    // the async cacher should re-execute this caller function after the caching is complete
}

var anotherCallerFunction = function(anotherParam){

    loadCache("anotherDataTarget",function(){
        anotherCallerFunction(anotherParam);
    });

}

var loadCache = function(cacheId,callback){

    asyncCall(cacheId, function(result){
        cache[cacheId] = result;

        cacheCallbackQueue.push(callback);
        // is there a way to get the caller function automatically 
        // without the need to pass it as callback function on the parameter

        checkCachingStatus(); 
    })

}

// check if caching is completed, 
// if the caching is completed, 
// it will execute all previously queued callback function
var checkCachingStatus = function(){
    var cachingStatus = "complete";
    if(!cache["aDataTarget"] || !cache["anotherDataTarget"]){
        cachingStatus = "incomplete";
    }

    if(cachingStatus === "complete"){
        for(var key in cacheCallbackQueue){
            cacheCallbackQueue[key]();
        }
    }
};

theCallerFunction("whatever");
anotherCallerFunction(666);

我不确定我是否正在编写'正确的javascript方式',我愿意接受其他建议

1 个答案:

答案 0 :(得分:0)

  

在vanilla Javascript(ES2015)中有没有办法获得调用函数并在异步调用完成后重新执行它而不需要将其作为回调函数传递?

不是标准的JavaScript,没有。一些JavaScript引擎添加了非标准扩展名caller,但它不是标准的,在严格模式下是禁止的。

  

我不确定我是否正在编写'正确的javascript方式',我愿意接受其他建议

有一些“正确的JavaScript方式”:

  • 将函数传递给loadCache,你说你不想做(但你正在做的事)
  • loadCache返回一个对象,该对象提供对事件进行描述的方法,并且具有您可以订阅的“重试”事件;但是订阅一个事件就意味着传递一个处理函数,...你已经说过你不想这样做了: - )

说了这么多,还不清楚为什么loadCache 需要重新调用调用它的函数。处理这个的标准方法是使用promises(你可以在ES5中使用polyfill; polyfill甚至不是那么大):loadCache会返回一个promise,然后调用它的代码会使用它:

var theCallerFunction = function(someParam) {
    loadCache(/*...*/)
        .then(function(data) {
            // Use `data` here
        })
        .catch(function() {
            // Handle failure here
        });
    // Probably no code here, since you want to wait for the cached information
};

或者如果调用者应该处理错误:

var theCallerFunction = function(someParam) {
    return loadCache(/*...*/)
        .then(function(data) {
            // Use `data` here
        });
};