defer.promise 不等待对象解析

defer.promise not waiting for object to resolve

本文关键字:对象 等待 promise defer      更新时间:2023-09-26

我正在尝试使用 resolve 在路由内延迟加载控制器:

.when('/somepage', {
        resolve: {
            load: function (loadDependencies, $q) {
                return loadDependencies.load(['controllers/myCtrl.js'], [], []);
            }
        },
        templateUrl: 'views/some-template.html'
    })

这是我的负载依赖项工厂:

app.factory('loadDependencies', function ($q, $timeout) {
    return {
        load: function (Controllers,cssFiles,modules) {
            var jsPath = "scripts/",
                cssPath = "css/",
                head = document.getElementsByTagName("head")[0],
                deffered = $q.defer(),
                jsReady = 0,
                jsShouldBeReady = Controllers.length;
            Controllers.forEach(function (arrayItem) {
                var js = document.createElement("script");
                js.src = jsPath + arrayItem;
                head.appendChild(js);
                js.onload = function () {
                    jsReady++;
                    if (jsReady == jsShouldBeReady) { // if loaded files equal to controllers length, then they all finished loading - so resolve deffered
                        deffered.resolve(true);
                    }
                };
                js.onerror = function() {
                    alert("Cannot load js files. Pleae try again later");
                }; 
            });
            return deffered.promise;
        }
    }
});

我是 angular 的新手,但根据我的理解 - deffered.promise 应该等待承诺解决吗? 目前它只返回对象。我也试过这个:

deffered.promise.then(function () {
   // call back here
});

但是我不明白如何将解析的值返回给控制器。

首先 - 你的实际问题:如果你想在文件懒惰到达时加载控制器,你应该阅读这篇文章。您需要注册控制器才能延迟加载它们。

至于承诺:

我非常支持总是在尽可能低的水平上承诺。您的代码使用异步信号量自行执行聚合 - 该逻辑已经通过执行相同操作的$q.all为您实现,只是具有更好的错误处理。

function loadScript(url){
    var scr = document.createElement("script");
    scr.src = url;
    var d = $q.defer();
    scr.onload = function(){ d.resolve(scr); };
    scr.onerror = function(e){ d.reject(e); };
    return d.promise;
}

该代码非常清楚,现在,您可以加载多个承诺并通过$q.all等待它们:

function load(files){
    return $q.all(files.map(loadScript));
}
load([url1, url2, url2]).then(function(){
    // all files are loaded, just like in your example.
});