简体   繁体   English

科尔多瓦文件检查异步写入

[英]cordova file check write asynchronously

I use cordovaFile method to test if file exists in several directories. 我使用cordovaFile方法测试文件是否存在于多个目录中。 When I find one, I do some actions and break the for loop. 找到一个时,我将执行一些操作并中断for循环。

But, cordovaFile.checkFile (like writeFile or others methods) works asynchronously, so the CLI displays me (for console.log) : 但是,cordovaFile.checkFile(例如writeFile或其他方法)是异步工作的,因此CLI会向我显示(对于console.log):

1     890383   log      ===== file_created =====
2     890389   log      object
3     890395   log      null
5     890492   log      ===== file_created =====
6     890494   log      object
7     890496   log      null
9     890556   log      ===== file_created =====
10    890558   log      object
11    890559   log      null
13    890626   log      ===== file_created =====
14    890627   log      object
15    890628   log      null
17    890671   log      ===== file_created =====
18    890672   log      object
19    890674   log      null

Is there a way to run cordova.checkFile synchronously ? 有没有一种方法可以同步运行cordova.checkFile?

My code (originnaly in controllers) : 我的代码(最初在控制器中):

dir_list = [
    cordova.file.applicationDirectory,
    cordova.file.externalRootDirectory,
    cordova.file.externalDataDirectory,
    cordova.file.applicationStorageDirectory,
    cordova.file.dataDirectory
];

for (index = 0; index < dir_list.length; ++index) {
    current_dir = dir_list[index];

    file_created = null;
    $cordovaFile.checkFile(current_dir, filename)
    .then(function (success) {
        file_created = true;
    }, function (error) {
        file_created = false;
    }

    console.log('===== file_created =====');
    console.log(typeof file_created);
    console.log(JSON.stringify(file_created));

    if (file_created) {
        // Some actions
        break;
    }
});

Solution inspired by Aaron Franco's answer 受亚伦·佛朗哥答案启发的解决方案

// This function will run by backup function
$scope.write_file_list = function(file_list, filename, content) {
  if (file_list.length) {
    current_dir = file_list[0];
    $cordovaFile.writeFile(current_dir, filename, content, true).then(
    function(result) {
      // Action if file saved
    }, function(err) {
      file_list.splice(0, 1);
      $scope.write_file_list(file_list, filename, content);
    });
  }
  else {
    // Action if none file saved
  }

};

// This function is called by controller
$scope.backup = function() {
    dir_list = [
        cordova.file.applicationDirectory,
        cordova.file.externalRootDirectory,
        cordova.file.externalDataDirectory,
        cordova.file.applicationStorageDirectory,
        cordova.file.dataDirectory
    ];
    content = 'content file';
    filename = 'test.txt';
    $scope.write_file_list(dir_list, filename, content);
}

You should execute your code inside a method that can be called after the file is created. 您应该在创建文件后可以调用的方法内执行代码。

dir_list = [
    cordova.file.applicationDirectory,
    cordova.file.externalRootDirectory,
    cordova.file.externalDataDirectory,
    cordova.file.applicationStorageDirectory,
    cordova.file.dataDirectory
];

for (index = 0; index < dir_list.length; ++index) {
    current_dir = dir_list[index];
    $cordovaFile.checkFile(current_dir, filename)
    .then(function (success) {
        console.log('===== file_created =====');
        // do some stuff here that deals with the created file.
    }, function (error) {
        // do something with error
    }

});

By doing it this way, there is no need to flag the file creation. 通过这种方式,无需标记文件创建。 You know the file was created when your success function is called. 您知道文件是在调用成功函数时创建的。

Cordova is designed to run on the main thread of your application, so anything you do synchronously will block that thread. Cordova被设计为在应用程序的主线程上运行,因此,您同步执行的任何操作都会阻塞该线程。 This is why Cordova apps are written asynchronously. 这就是为什么Cordova应用程序是异步编写的。 That and the fact that JavaScript is an Async language to begin with. 那就是JavaScript最初是一种异步语言的事实。

The alternative would be to use a promise. 另一种选择是使用承诺。

<script src="https://www.promisejs.org/polyfills/promise-7.0.4.min.js"></script>

You should be able to use it in this way to check one file. 您应该能够以这种方式使用它来检查一个文件。

dir_list = [
    cordova.file.applicationDirectory,
    cordova.file.externalRootDirectory,
    cordova.file.externalDataDirectory,
    cordova.file.applicationStorageDirectory,
    cordova.file.dataDirectory
];
function checkIfFileExist(filename) {
   return new Promise(function(resolve, reject){
     for (index = 0; index < dir_list.length; ++index) {
       current_dir = dir_list[index];
       $cordovaFile.checkFile(current_dir, filename).then(resolve, reject);
     }
   });
 }

checkIfFileExist(filename).then(function (successData) { 
    // file exists here
}, function (err) { 
    // file doesn't exist here
});

That should allow you to check one at a time. 那应该允许您一次检查一个。 For more details on using promises: 有关使用诺言的更多信息:

http://ramkulkarni.com/blog/using-javascript-promises-with-cordova/ http://ramkulkarni.com/blog/using-javascript-promises-with-cordova/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM