Windows 8 Javascript应用程序激活/启动延迟 [英] Windows 8 Javascript app activation/launch deferral

查看:92
本文介绍了Windows 8 Javascript应用程序激活/启动延迟的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以目前在我编写的Windows 8 WinJS应用程序中,我试图在app启动序列中加载xml文件,而启动画面仍在显示,因为需要这个xmldoc元素当主页加载时,主页的加载将在没有它的情况下失败。



这是我在default.js中的启动顺序:



 (function(){use strict; var activation = Windows.ApplicationModel.Activation; var app = WinJS.Application; var nav = WinJS.Navigation; var sched = WinJS.Utilities.Scheduler; var ui = WinJS.UI; app.addEventListener(activated,function(args){if(args.detail.kind === activation.ActivationKind.launch){if(args.detail.previousExecutionState) !== activation.ApplicationExecutionState.terminated){// TODO:这个a pplication已经新推出。在这里初始化//您的应用程序。 console.log(Newly Launched!); var localSettings = Windows.Storage.ApplicationData.current.localSettings; WinJS.Namespace.define(MyGlobals,{localSettings:localSettings}); // APP RUN TYPE CHECK AND SEQUENCE(FIRST RUN / NOT FIRST RUN):if(MyGlobals.localSettings.values ['firstRunCompleted']){console.log(NOT FIRST RUN!); // CACHE VERSION CHECK。如果APP已经更新,请在此处启动新添加的缓存值:} else {console.log(FIRST RUN!)MyGlobals.localSettings.values ['firstRunCompleted'] = true; }; // loadXML的();用这个做过很多尝试。不起作用。 } else {// TODO:此应用程序已从暂停状态重新激活。 //在此处恢复应用程序状态var currentVolume = app.sessionState.currentVolume; if(currentVolume){console.log(RESTORE FROM SUSPENSION);的console.log(currentVolume); }; } nav.history = app.sessionState.history || {}; nav.history.current.initialPlaceholder = true; //优化应用程序的负载,在显示启动屏幕时,执行高优先级的计划工作。 ui.disableAnimations(); var p = ui.processAll()。then(function(){return nav.navigate(nav.location || Application.navigator.home,nav.state);})。then(function(){return sched.requestDrain( sched.Priority.aboveNormal + 1);})。then(function(){ui.enableAnimations();}); args.setPromise(P); args.setPromise(WinJS.UI.processAll()。then(function completed(){loadSavedColour(); //填充设置窗格并将命令绑​​定到设置弹出窗口.WinJS.Application.onsettings = function(e){e.detail。 applicationcommands = {helpDiv:{href:html / Help.html,title:WinJS.Resources.getString(settings_help)。value},aboutDiv:{href:html / About.html,title :WinJS.Resources.getString(settings_about)。value},settingsDiv:{href:html / Settings.html,title:WinJS.Resources.getString(settings_settings)。value},}; WinJS。 UI.SettingsFlyout.populateSettings(e);}  



尽可能看看我在哪里有loadXML()的注释行,这就是我需要发生loadXML()函数的地方。
这是我的loadXML()函数on:



< pre class =snippet-code-js lang-js prettyprint-override> function loadXML(){Windows.ApplicationModel.Package.current.installedLocation.getFolderAsync(foldername)。then(function(externalDtdFolder) ){externalDtdFolder.getFileAsync(MyGlobals.localSettings.values ['currentBook'])。done(function(file){Windows.Data.Xml.Dom.XmlDocument.loadFromFileAsync(file).then(function(doc){WinJS.Namespace .define(MyGlobals,{xmlDoc:doc,}); })})}); };



(loadXML是一个工作函数,适用于其他场景)



然而,问题是在loadXML函数完成之前,应用程序启动画面消失了,下一个home.html主页加载,启动随附的主页.js,它的函数需要loadXML应该具有的MyGlobals.xmlDoc对象。这会立即崩溃应用程序,因为MyGlobals.xmlDoc未定义/ null。
我以前通过在home.js中直接在home.html页面中运行loadXML来使这个应用程序工作,但是在那个场景中,每次导航到页面时都会重新加载XML文档,浪费时间和资源。因此,我正在尝试将xmldocument加载到app启动/初始化中。
非常感谢!

解决方案

loadXML 具有异步功能你需要处理它。



你不应该期望 loadFromFileAsync (或任何其他异步函数)在它返回之前完成给来电者。如果您的代码没有等待,您会发现在需要时不会设置 MyGlobals.xmlDoc 值。



我在下面将其重命名为更准确的行为。最大的变化是它返回一个 Promise ,调用者可以使用它来正确等待加载Xml文档。这个 Promise 可以与其他 Promise 一起使用,以便在多个条件下等待(或者在这种情况下) ,其他异步工作)。

  function loadXMLAsync(){
返回新的WinJS.Promise(函数(完成,错误,进度){
var localSettings = MyGlobals.localSettings.values;
var installedLocation = Windows.ApplicationModel.Package.current.installedLocation;
installedLocation.getFolderAsync(foldername)。then( function(externalDtdFolder){
externalDtdFolder.getFileAsync(values ['currentBook'])。done(function(file){
Windows.Data.Xml.Dom.XmlDocument.loadFromFileAsync(file).then(function (doc){
complete(doc);
});
});
});
});
};

然后,在使用中:

  loadXmlAsync()。then(function(doc){
WinJS.Namespace.define(MyGlobals,{
xmlDoc:doc,
});
//以及任何其他应该等到此完成的代码
});

上面的代码不能处理错误。


So currently in a windows 8 WinJS app I'm coding, I am trying to get the loading of an xml file to take place in the app startup sequence, while the splash screen is still showing, as this xmldoc element is needed for when the home page loads, and loading of the home page will fail without it.

This is my initiation sequence in default.js:

(function () {
    "use strict";

    var activation = Windows.ApplicationModel.Activation;
    var app = WinJS.Application;
    var nav = WinJS.Navigation;
    var sched = WinJS.Utilities.Scheduler;
    var ui = WinJS.UI;

    app.addEventListener("activated", function (args) {
        if (args.detail.kind === activation.ActivationKind.launch) {
            if (args.detail.previousExecutionState !== activation.ApplicationExecutionState.terminated) {
                // TODO: This application has been newly launched. Initialize
                // your application here.
                console.log("Newly Launched!");

                var localSettings = Windows.Storage.ApplicationData.current.localSettings;
                WinJS.Namespace.define("MyGlobals", { localSettings: localSettings });

                // APP RUN TYPE CHECK AND SEQUENCE (FIRST RUN / NOT FIRST RUN):
                if (MyGlobals.localSettings.values['firstRunCompleted']) {
                    console.log("NOT FIRST RUN!");
                    // CACHE VERSION CHECK. IF APP HAS BEEN UPDATED, INITIATE NEWLY ADDED CACHE VALUES HERE:
                } else {
                    console.log("FIRST RUN!")
                    MyGlobals.localSettings.values['firstRunCompleted'] = true;
                };


                //loadXML(); have tried many things with this. doesn't work.

                

            } else {
                // TODO: This application has been reactivated from suspension.
                // Restore application state here.
                var currentVolume = app.sessionState.currentVolume;
                if (currentVolume) {
                    console.log("RESTORE FROM SUSPENSION");
                    console.log(currentVolume);
                };
            }

            nav.history = app.sessionState.history || {};
            nav.history.current.initialPlaceholder = true;

            // Optimize the load of the application and while the splash screen is shown, execute high priority scheduled work.
            ui.disableAnimations();
            var p = ui.processAll().then(function () {
                return nav.navigate(nav.location || Application.navigator.home, nav.state);
            }).then(function () {
                return sched.requestDrain(sched.Priority.aboveNormal + 1);
            }).then(function () {
                ui.enableAnimations();
            });

            args.setPromise(p);
            args.setPromise(WinJS.UI.processAll().then(function completed() {

                loadSavedColour();
                 
                // Populate Settings pane and tie commands to Settings flyouts.
                WinJS.Application.onsettings = function (e) {
                    e.detail.applicationcommands = {
                        "helpDiv": { href: "html/Help.html", title: WinJS.Resources.getString("settings_help").value },
                        "aboutDiv": { href: "html/About.html", title: WinJS.Resources.getString("settings_about").value },
                        "settingsDiv": { href: "html/Settings.html", title: WinJS.Resources.getString("settings_settings").value },
                    };
                    WinJS.UI.SettingsFlyout.populateSettings(e);
                }
                 

As you can see where I have the commented line of "loadXML()", that is where I need the loadXML() function to take place. Here is my loadXML() function:

function loadXML() {
        Windows.ApplicationModel.Package.current.installedLocation.getFolderAsync("foldername").then(function (externalDtdFolder) {
            externalDtdFolder.getFileAsync(MyGlobals.localSettings.values['currentBook']).done(function (file) {
                Windows.Data.Xml.Dom.XmlDocument.loadFromFileAsync(file).then(function (doc) {
                    WinJS.Namespace.define("MyGlobals", {
                        xmlDoc: doc,
                    });
                })
            })
        });
    };

(loadXML is a working function and works in other scenarios)

However, the issue is that before the loadXML function finishes, the app splash screen goes away, and the next home.html home page loads, which starts the accompanying home.js, which has a function that requires the MyGlobals.xmlDoc object that loadXML should have made. This immediately crashes the app, as MyGlobals.xmlDoc is undefined/null. I used to have this app working by running loadXML in home.js for the home.html page directly, but in that scenario the XML document is reloaded every time navigation is made to the page, wasting time and resources. As such, I'm trying to move the xmldocument loading into the app startup/initialization. Thanks a lot!

解决方案

loadXML has async functionality and you need to handle that.

You shouldn't expect that the loadFromFileAsync (or any of the other async functions) have completed before it returns to the caller. If your code doesn't wait, you'll find that the MyGlobals.xmlDoc value won't be set when you need it.

I've renamed it below to be more accurate as to its behavior. The big change is that it returns a Promise that can be used by the caller to properly wait for the Xml doc to be loaded. This Promise could be used with other Promises to wait on multiple conditions if you'd like (or in the case, other async work).

function loadXMLAsync() {
    return new WinJS.Promise(function (complete, error, progress) {
        var localSettings = MyGlobals.localSettings.values;
        var installedLocation = Windows.ApplicationModel.Package.current.installedLocation;
        installedLocation.getFolderAsync("foldername").then(function (externalDtdFolder) {
            externalDtdFolder.getFileAsync(values['currentBook']).done(function (file) {
                Windows.Data.Xml.Dom.XmlDocument.loadFromFileAsync(file).then(function (doc) {
                    complete(doc);
                });
            });
        });
    });
};

Then, in use:

loadXmlAsync().then(function(doc) {
    WinJS.Namespace.define("MyGlobals", {
        xmlDoc: doc,
    });
    // and any other code that should wait until this has completed
});

The code above does not handle errors.

这篇关于Windows 8 Javascript应用程序激活/启动延迟的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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