2012-08-14 24 views
2

中使用我目前在Windows 8/WinRT應用程序中讀取文件時遇到問題。我有一個簡單的導航風格的應用程序,幾個頁面可以訪問相同的數據,我有一個data.js文件,它定義了一個包含多個成員的命名空間(Data)。應用程序的一部分將項目保存到存儲在應用程序本地數據文件夾中的txt文件中。但在其他一些頁面上,我需要閱讀這些內容或檢查以前保存的項目列表中是否存在項目。爲此,我在data.js文件中添加了另一個方法。麻煩的是,當我調用這個方法來檢查一個項目的存在時,由於異步性質它不會立即返回值,但頁面特定的js文件中的其餘代碼似乎仍然在它之前執行跳回到解析。這意味着檢查項目的邏輯似乎不起作用。我有一種感覺它的下跌給我使用的任何.done或者。然後,但我的代碼如下:從使用WinJS讀取的文件返回值以便在第

DATA.JS 
    var doesItemExist= function(item_id){ 

    var appFolder = Windows.Storage.ApplicationData.current.localFolder; 
    //note I've tried this with and without the first "return" statement 
    return appFolder.getFileAsync(dataFile).then(function (file) { 
     Windows.Storage.FileIO.readTextAsync(file).done(function (text) { 
      try { 
       var json = JSON.parse(text); 
       if (json) { 
        for (var i = 0; i < json.items.length; i++) { 
         var temp_item = json.items[i]; 
         if (temp_item.id === item_id) { 
          return true; 
          break; 
         } 
        } 
       } else { 
        return false; 
       } 
      } catch (e) { 
       return false; 
       console.log(e); 
      } 
     }, function (e) { return false;console.log(e); }); 
    }, function (e) { // error handling 
     return false; 
     console.log(e); 

    }); 
} 
WinJS.Namespace.define("Data", { 
    doesItemExist: doesItemExist 
}); //all of the above is wrapped in a self executing function 

然後在Page.js我有以下幾點:

var add = document.getElementById('add'); 
     if (Data.doesItemExist(selected_item.id)) { 
      add.style.display = 'block'; 
     } else { 
      add.style.display = 'none'; 
     } 

所有的變量這裏是分配的,並且調試不會產生任何錯誤,控制只是在它碰到getFileAsync之後,但在它通過for循環之前似乎回到if/else語句。但後來它確實進入了for循環,但在if語句結束之後。我猜這是所有的異步性質,但我不知道如何繞過它。有任何想法嗎?

謝謝

+0

我想你在這裏需要的是讓data.js中的代碼返回一個Promise,然後你會在頁面特定的JS文件中使用它來獲取布爾值。讓我看看我一直在努力的應用程序之一,我會張貼一些代碼來簡要說明。 – devhammer 2012-08-14 14:58:57

回答

3

一個承諾應該在這裏工作。

我創建了一個新的導航應用,並增加了一個Data.js文件包含以下代碼:

(function() { 
    var appData = Windows.Storage.ApplicationData; 

    function doesItemExist(item_id) { 
     return new WinJS.Promise(
      function (completed, error, progress) { 
       var exists = false; 
       appData.current.localFolder.createFileAsync("data.txt", Windows.Storage.CreationCollisionOption.openIfExists).then(
        function (file) { 
         Windows.Storage.FileIO.readTextAsync(file).then(
          function (fileContents) { 
           if (fileContents) { 
            if (fileContents = "foo!") { 
             completed(true); 
            } 
            else { 
             completed(false); 
            } 
           } 
           else { 
            completed(false); 
           } 
          } 
         ); 
        }, 
        function (e) { 
         error(e); 
        } 
       ); 
      } 
     ); 
    } 

    WinJS.Namespace.define("Data", { 
     doesItemExist: doesItemExist 
    }); 
})(); 

請注意,我已經簡化了檢索和解析該文件的代碼,因爲這不是真正相關的解決問題。重要的是,一旦你確定了物品是否存在,你可以撥打完成(存在),觸發你要返回的諾言的.then或.done。請注意,如果發生異常,則會調用錯誤(e),正如我在調用createFileAsync時發生異常(我使用此調用而不是getFileAsync,當我希望能夠創建文件時不存在,或者使用openIfExists選項返回現有文件)。

然後,在Home.js,添加以下代碼到準備處理程序:

var itemExists; 

var itemExistsPromise = Data.doesItemExist(42); 
itemExistsPromise = itemExistsPromise.then(function (exists) { 
    itemExists = exists; 
    var content = document.getElementById("content"); 
    content.innerText = "ItemExists is " + itemExists; 
}); 

itemExistsPromise.done(function() { 
    var a = 42; 
}); 

var b = 0; 

上面的代碼將變量itemExistsPromise從在Data.js函數返回的承諾,然後使用Promise的.then函數中的一個匿名函數將變量itemExists設置爲從doesItemExist Promise返回的布爾值,並從Home.html中獲取<p>標記(我添加了一個id,以便從代碼中獲取它)以及設置其文字以指示項目是否存在)。因爲我在調用.then而不是.done,調用返回另一個promise,它被傳遞給itemExistsPromise變量。

接下來,我調用itemExistsPromise.done來完成任何必須等待上面的.then工作完成後的工作。

如果您在「var a = 42」和「var b = 0」(僅用於設置斷點的目的)行以及「itemExists = exists」行上設置斷點,則應該找到當執行各個部分時,這可以讓您控制所需的控制。

希望有幫助!

+2

我會推薦你​​的承諾鏈,而不是嵌套承諾,你返回承諾和。然後,然後縮進他們。使其更具可讀性。 – 2012-08-14 18:44:14

+0

@DominicHopton感謝您的建議。我認爲這是一個個人喜好的問題,我已經嘗試過兩種方法,還沒有就我喜歡的方式做出決定。我發現嵌套更簡潔一點,但是可讀性有成本。 – devhammer 2012-08-14 22:16:43

+0

我發現嵌套只是把背景吹走了。這使得很難理解順序並導致錯誤處理的複雜性。但是,是的,這是一個偏好的事情。:) – 2012-08-14 23:26:38

相關問題