locked
Is there a delay for StorageItem.getItemsAsync()?

    Question

  • Hi,

    I want to get the file in the specified path. e.g. "C:\Users\cor\Documents\New folder\folder2\1.txt". however, Metro cannot support multi level directory, so i wrote a method as below.

    The method can give me correct result if i debug and step run it. But i cannot get the callback funtion running if i run it directly.

    console.log("enter2"); didn't output "enter2". the list was undefined.

    Maybe it was caused by getItemsAsync()? Is there any way to avoid or fix this issue? I cannot find a sync method in WinJS.

    //call
    getItem(Windows.Storage.KnownFolders.documentsLibrary, "New folder\\folder2\\1.txt", "file");
    
    var returnItem;
    
    function getItem(parentStorage, itemPath, itemType) {
        console.log("enter");
        var names = itemPath.split("\\");
        var isEnd = false;
        if(names.length == 1)
            var isEnd = true;
    
        parentStorage.getItemsAsync().then(
                function (list) {
                    console.log("enter2");
                    for (var i = 0; i < list.size; ++i) {
                        var goal = list[i];
                        if (isEnd) {
                            if ((itemType == "file" && goal.isOfType(Windows.Storage.StorageItemTypes.file))
                                || (itemType == "folder" && goal.isOfType(Windows.Storage.StorageItemTypes.folder)))
                                if (goal.name == names[0]) {
                                    returnItem = goal;
                                }
                        }
                        if (!isEnd && goal.isOfType(Windows.Storage.StorageItemTypes.folder)) {
                            if (goal.name == names[0]) {
                                var newParentStorage;
                                parentStorage.getFolderAsync(goal.name).then(
                                    function (folder) { newParentStorage = folder;}
                                    );
                                var newItemPath = itemPath.substr(itemPath.indexOf("\\") + 1);
                                getItem(newParentStorage, newItemPath, itemType);
                                }
                        }
                        }
                });
    }

    Tuesday, April 24, 2012 8:35 AM

Answers

  • Glad that you found a more direct way to access a file in nested folders.

    Regarding your original code, yes there is a delay in all of the 'async' methods and require the use of the then() or done() methods to access the results properly.  In your example, there is (at least) one bug in the last phrase...

    if (goal.name == names[0]) {
                                var newParentStorage;
                                parentStorage.getFolderAsync(goal.name).then(
                                    function (folder) { newParentStorage = folder;}
                                    );
                                var newItemPath = itemPath.substr(itemPath.indexOf("\\") + 1);
                                getItem(newParentStorage, newItemPath, itemType); //<--------Will have the wrong newParentStorage value!!!!
                                }

    where the call to getItem(newParentStorage...) will not have the updated newParentStorage value since it is outside the then() method.  That is, you will be calling the function before the asynchronous operation has completed.  (If you are stepping through the code in the debugger, there is time for this operation to complete.)

    In my opinion, recursively calling functions with async methods is very complex and should be avoided.  Thankfully, you have found a way to reach your goal without resorting to this technique.

    • Proposed as answer by jrboddie Tuesday, April 24, 2012 12:57 PM
    • Marked as answer by Jiankui Wednesday, April 25, 2012 1:02 AM
    Tuesday, April 24, 2012 12:52 PM

All replies

  • Oh.. i found i can get the file via Windows.Storage.KnownFolders.documentsLibrary.getFileAsync("New folder\\folder2\\1.txt").then();

    But i still want to know why the function cannot work if it was ran directly. Thanks!

    Tuesday, April 24, 2012 8:50 AM
  • Glad that you found a more direct way to access a file in nested folders.

    Regarding your original code, yes there is a delay in all of the 'async' methods and require the use of the then() or done() methods to access the results properly.  In your example, there is (at least) one bug in the last phrase...

    if (goal.name == names[0]) {
                                var newParentStorage;
                                parentStorage.getFolderAsync(goal.name).then(
                                    function (folder) { newParentStorage = folder;}
                                    );
                                var newItemPath = itemPath.substr(itemPath.indexOf("\\") + 1);
                                getItem(newParentStorage, newItemPath, itemType); //<--------Will have the wrong newParentStorage value!!!!
                                }

    where the call to getItem(newParentStorage...) will not have the updated newParentStorage value since it is outside the then() method.  That is, you will be calling the function before the asynchronous operation has completed.  (If you are stepping through the code in the debugger, there is time for this operation to complete.)

    In my opinion, recursively calling functions with async methods is very complex and should be avoided.  Thankfully, you have found a way to reach your goal without resorting to this technique.

    • Proposed as answer by jrboddie Tuesday, April 24, 2012 12:57 PM
    • Marked as answer by Jiankui Wednesday, April 25, 2012 1:02 AM
    Tuesday, April 24, 2012 12:52 PM
  • Without debugging your code... it looks like you are not returning a promise from getItem, so you are just falling though the code.  Trace this with the debugger and you will see what I mean.

    -Jeff


    Jeff Sanders (MSFT)

    Tuesday, April 24, 2012 12:53 PM
    Moderator