WinJS如何使appendTextAsync等待文件可用

时间:2014-09-17 13:19:14

标签: file-io promise winjs

我有这样的代码用于登录我的WinJS应用程序:

function setupFileLog() {
    var logFn = function (message, tag, type) {
        if (!log_file) return; // log_file is global, setup below with a StorageFile object
        Windows.Storage.FileIO.appendTextAsync(log_file, tag + ' ' + type + ': ' + message)
            .done(null, function (error) {
                // I have a breakpoint here to catch the error
                var msg = error.detail.message;
                }
            });
    };

    app_folder.createFolderAsync('logs', Windows.Storage.CreationCollisionOption.openIfExists)
       .then(function (logfolder) {
           var now = new Date();
           var logfilename = config.device + "_" + now.toDateString() + ".log";
           return logfolder.createFileAsync(logfilename, Windows.Storage.CreationCollisionOption.openIfExists)
       })
       .done(function (file) {
           log_file = file; // save in global var
           WinJS.Utilities.startLog({ tags: "myApp", action: logFn });
       });
}

setupFileLog();

// ...
// do stuff and log things
// ...

WinJS.log && WinJS.log('I did some stuff', 'myApp','info');
WinJS.log && WinJS.log('I got an error: '+error, 'myApp','error');

间歇性地,我在logFn中收到错误“进程无法访问该文件,因为它正被另一个进程使用”或“访问被拒绝”。我认为由于appendText调用的异步性质并且在上一次日志记录调用完成写入之前尝试获取日志文件的句柄,因此多次调用WinJS.log会发生冲突。

我可以让appendTextAsync等到日志文件没有被使用吗?我找不到任何调用来检查文件是否繁忙。我认为有一种方法可以使appendTextAsync以同步方式执行,但我想避免在所有情况下都这样做,因为这只是一个间歇性的情况。

1 个答案:

答案 0 :(得分:3)

您可以创建一个按顺序自动执行的调用链:

function setupFileLog() {
    var log_file = app_folder.createFolderAsync('logs', Windows.Storage.CreationCollisionOption.openIfExists)
   .then(function (logfolder) {
        var now = new Date();
        var logfilename = config.device + "_" + now.toDateString() + ".log";
        return logfolder.createFileAsync(logfilename, Windows.Storage.CreationCollisionOption.openIfExists)
    });

    WinJS.Utilities.startLog({
        tags: "myApp",
        action: function log_fn(message, tag, type) {
             log_file = log_file.then(function(file) {
                 return Windows.Storage.FileIO.appendTextAsync(file, tag + ' ' + type + ': ' + message)
                 .then(function() {
                     return file;
                 }, function (error) {
                    // I have a breakpoint here to catch the error
                    var msg = error.detail.message;
                    return file; // for further logs, or
                    throw error; // go stop logging
                 });
            });
        }
    });
}

log_fn的每次通话都会对appendTextAsync承诺进行另一次log_file调用。奖励是在尚未创建日志文件时已经链接了调用,而不是简单地删除日志行。