WinJS中的条件承诺

时间:2014-07-28 14:22:01

标签: javascript windows-store-apps promise winjs

我有两段代码,可能会在我的应用启动时运行,也可能不运行。两者都产生一个messageDialog,所以第二个必须等到第一个。我正在尝试使用promises来做到这一点,但我遇到了返回值的问题。有人能指出我正确的方向吗?

WinJS.Promise.as()
   .then(function () {
       // readTempFile returns a promise, see code below
       if (localSettings.values["lastContent"] != 0) {
            return readTempFile();
       }else{
            // what am I supposed to return here? false? 
       }
   })
   .then(function () {
       // check for release notes
       if (localSettings.values["release"] == null) {
            var updates = "Updates in this version";
            var msg = new Windows.UI.Popups.MessageDialog(updates, "Updates");
            msg.commands.append(new Windows.UI.Popups.UICommand("OK", null, 0));
            msg.showAsync();
       }
   });

function readTempFile(){
    return new WinJS.Promise(function (complete, error, progress) {
        // is my try / catch block redundant here? 
        try {
            tempFolder.getFileAsync("tempFile.txt")
                .then(function (file) {
                    file.openReadAsync().done(function (stream) {
                         // do stuff with the file
                    });
                    var msg = new Windows.UI.Popups.MessageDialog("unsaved work", "Warning");
                    msg.commands.append(new Windows.UI.Popups.UICommand("OK", null, 0));
                    msg.showAsync();
                    complete();
                }, function () {
                    // file not found
                    error();
                });
        }
        catch (e) {
            logError(e);
            error();
        }
    });
}

如果两个条件都为真,我会收到拒绝访问错误。据我了解,readTempFile()返回一个我的第一个then()语句应该接受的promise对象。但是如果达到第一个条件,我就不会返回任何东西。在这种情况下,我认为这不重要,因为它只是落到下一个then,但它不是很好的编程。

编辑:

修改readTempFile函数以显示它生成MessageDialog。

2 个答案:

答案 0 :(得分:1)

好吧,让我们尝试一个类比:

function fetchIfNotCached(){
    if(!cached){
        doSomething();
    }
    // nothing here
}

这与您的情况完全一样,只是异步。因为它利用了promises你挂钩返回值所以:

  我应该在这里回到什么地方?假?

你想要的任何东西,我个人可能只是省略它并将其重构为if(!cached) return doSomething()中的.then。 Promise链和compose,你不需要从回调接口创建它们,除非有充分的理由这样做。

至于readTempFile,你做了很多过多的工作,因为看起来getFileAsync已经返回了一个承诺。这是deferred anti pattern的变体,可以重写为:

function(readTempFile){
   return tempFolder.getFileAsync("tempFile.txt").then(function (file) {
      return file.openReadAsync();
   }).then(function (stream) {
      // do stuff with the file, note the return as we wait for it
   });
}

答案 1 :(得分:0)

找到答案。在readTempFile函数中,我需要在我的messageDialog的done()中添加showAsync(),并将complete()调用放入其中。否则,complete()在对话框仍然启动时返回了承诺。

function readTempFile(){
    return new WinJS.Promise(function (complete, error, progress) {
        // is my try / catch block redundant here? 
        try {
            tempFolder.getFileAsync("tempFile.txt")
                .then(function (file) {
                    file.openReadAsync().done(function (stream) {
                         // do stuff with the file
                    });
                    var msg = new Windows.UI.Popups.MessageDialog("unsaved work", "Warning");
                    msg.commands.append(new Windows.UI.Popups.UICommand("OK", null, 0));
                    msg.showAsync().done(function(){
                        // must be inside done(), or it will return prematurely
                        complete();
                    });
                }, function () {
                    // file not found
                    error();
                    // have to add a complete in here too, or the app will 
                    // hang when there's no file                        
                    complete();
                });
        }
        catch (e) {
            logError(e);
            error();
        }
    });
}

经过几次实验,我自己想出来了。

关于在我的空else语句中需要返回的内容,它是另一个WinJS.Promise.as()

WinJS.Promise.as()
   .then(function () {
       // readTempFile returns a promise, see code below
       if (localSettings.values["lastContent"] != 0) {
            return readTempFile();
       }else{
            return WinJS.Promise.as()
       }
   })
   .then(function () {
       // check for release notes
       if (localSettings.values["release"] == null) {
            var updates = "Updates in this version";
            var msg = new Windows.UI.Popups.MessageDialog(updates, "Updates");
            msg.commands.append(new Windows.UI.Popups.UICommand("OK", null, 0));
            msg.showAsync();
       }
   });

我在Beginning Windows Store Application Development – HTML and JavaScript Edition By Scott Isaacs, Kyle Burns的Google图书预览中找到了答案,其中他们显示了另一个空的else语句,返回WinJS.Promise.as()