简体   繁体   English

使用$ .when时如何解决竞争条件

[英]How to resolve race condition when using $.when

I am trying to use jQuerys $.when() to load a bunch of localization resources before initializing the control on the client side: 我正在尝试使用jQuerys $.when() .when $.when()加载一堆本地化资源,然后在客户端上初始化控件:

var fooControl = (function($, kendo, _) {

    var
        initResources = function() {
            return $.when(
                window.clientResources.getAll("Messages").done(function(d) {
                    resources["Messages"] = d;
                }),
                window.clientResources.getAll("Cost").done(function(d) {
                    resources["Cost"] = d;
                })
            );
        },

        init = function(options) {
            /*... */
        }
}


//calling:
$(function() {
    fooControl.initResources().then(fooControl.init(options));
});

What I want to achieve is, that initResources waits until the resources are loaded up and assigned to their variables. 我想要实现的是,initResources等待直到资源被加载并分配给它们的变量。 They are either loaded up from an API endpoint or localStorage, if the data is cached. 如果已缓存数据,则可以从API端点或localStorage加载它们。 What actually happens is, that I am receiving an error Cannot read property 'CostType' of undefined , which indicates, that the Cost resources haven't been fully loaded yet. 实际发生的是,我收到一个错误, Cannot read property 'CostType' of undefined ,这表明Cost资源尚未完全加载。

So I suspect, that the calls to window.clientResources.getAll() are being resolved properly, but not the following .done method and this then results in a race condition, the resources are losing. 因此,我怀疑对window.clientResources.getAll()的调用已被正确解析,但未解决以下.done方法,这随后导致出现争用情况,资源正在丢失。

How can I make sure, that the whole call stack, including the assignment of the resources variable has been resolved and only then the following init function is called? 如何确保整个调用堆栈(包括resources变量的分配)都已解决,然后才调用以下init函数?

You are invoking the init immediately and passing its return value as success callback handler, A simple solution would be to use a anonymous method 您立即调用init并将其返回值作为成功回调处理程序传递,一个简单的解决方案是使用匿名方法

fooControl.initResources().then(function(){
    fooControl.init(options);
});

You could use $.Deferred() for this, then resolve that only when the resources have been loaded. 您可以$.Deferred()使用$.Deferred() ,然后仅在资源已加载时解决该问题。

Also as Satpal noted, then needs to be passed either an anonymous function or a function reference. 同样如Satpal所述, then需要传递匿名函数或函数引用。

var fooControl = (function($, kendo, _) {

    var initResources = function() {
        var deferred = $.Deferred();

        $.when(
            window.clientResources.getAll("Messages"),
            window.clientResources.getAll("Cost")
        ).done(function(msgData, costData) {
            resources["Messages"] = msgData;
            resources["Cost"] = costData;
            deferred.resolve();
        });

        return deferred.promise();
    },

    init = function(options) {
        /*... */
    }
}


//calling:
$(function() {
    fooControl.initResources().then(fooControl.init.bind(this, options));
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM