admin管理员组文章数量:1425200
I am calling a function from my AngularJS controller. When the function pletes execution, I would like to print the result after the function call.
This code is inside the controller, which is called on-tap
//count the number of files inside a directory
var count = countDir(cordova.file.dataDirectory +'/Images/');
console.log('Hello ');
console.log('Count of directory '+count);
Here is the countDir function. This function finds the number of files in a directory and then returns the count back
function countDir(path){
var count = 0;
console.log('Counting the files inside '+path);
window.resolveLocalFileSystemURL(path,
function (fileSystem) {
var reader = fileSystem.createReader();
reader.readEntries(
function (entries) {
var i;
for (i=0; i<entries.length; i++) {
console.log('File name ' + entries[i].name + ' added to count');
count++;
}
},
function (err) {
console.log(err);
}
);
}, function (err) {
console.log(err);
}
);
return count;
}
The challenge that I am facing is that, my calling code first prints 'Hello' and 'Count of directory 0' and then everything inside countDir is printed.
Is the call to countDir()
asynchronous? If so, how can I ensure that my calling code proceeds once countDir()
has returned a result.
I am calling a function from my AngularJS controller. When the function pletes execution, I would like to print the result after the function call.
This code is inside the controller, which is called on-tap
//count the number of files inside a directory
var count = countDir(cordova.file.dataDirectory +'/Images/');
console.log('Hello ');
console.log('Count of directory '+count);
Here is the countDir function. This function finds the number of files in a directory and then returns the count back
function countDir(path){
var count = 0;
console.log('Counting the files inside '+path);
window.resolveLocalFileSystemURL(path,
function (fileSystem) {
var reader = fileSystem.createReader();
reader.readEntries(
function (entries) {
var i;
for (i=0; i<entries.length; i++) {
console.log('File name ' + entries[i].name + ' added to count');
count++;
}
},
function (err) {
console.log(err);
}
);
}, function (err) {
console.log(err);
}
);
return count;
}
The challenge that I am facing is that, my calling code first prints 'Hello' and 'Count of directory 0' and then everything inside countDir is printed.
Is the call to countDir()
asynchronous? If so, how can I ensure that my calling code proceeds once countDir()
has returned a result.
- The second param of resolveLocalFileSystemURL (onSuccess) is async. The best way to handle this is to broadcast (stackoverflow./a/19446975/2608451) an event to your controller from inside the onSuccess body, so after the for loop inside the readEntries – Gecko Commented Sep 4, 2016 at 7:29
3 Answers
Reset to default 3Yes, the .resolveLocalFileSystemUrl is async; you could tackle your issue using $q promise:
function countDir(path){
var deff = $q.defer();
var count = 0;
console.log('Counting the files inside '+path);
window.resolveLocalFileSystemURL(path,
function (fileSystem) {
var reader = fileSystem.createReader();
reader.readEntries(
function (entries) {
var i;
for (i=0; i<entries.length; i++) {
console.log('File name ' + entries[i].name + ' added to count');
count++;
}
deff.resolve(count);
},
function (err) {
console.log(err);
deff.reject(err);
}
);
}, function (err) {
console.log(err);
deff.reject(err);
}
);
return deff.promise;
}
And consume it as:
var count =0 ;
countDir(cordova.file.dataDirectory +'/Images/')
.then( function(result){ count = result},
function(err){ //handle error }
);
The anonymous functions furnished to both window.resolveLocalFileSystemURL
and reader.readEntries
are invoked asynchronously. The "AngularJS way" to handle this is to use the $q
service to create and return a promise.
function countDirPromise(path){
//create $q.defer object
var q = $q.defer();
var count = 0;
console.log('Counting the files inside '+path);
$window.resolveLocalFileSystemURL(path,
function onUrlSuccess(fileSystem) {
var reader = fileSystem.createReader();
reader.readEntries(
function onReaderSuccess(entries) {
var i;
for (i=0; i<entries.length; i++) {
console.log('File name ' + entries[i].name + ' added to count');
count++;
}
//resolve with count
q.resolve(count);
},
function onReaderError(err) {
console.log(err);
//reject with error
q.reject(err);
}
);
}, function onUrlError(err) {
console.log(err);
//reject with error
q.reject(err);
}
);
//return count promise
return q.promise;
}
As you can see, there are four nested function: onUrlSuccess
, onUrlError
, onReaderSuccess
, and onReaderError
. Those functions get invoked asynchronously. The promise resolves with the value count
if both onUrlSuccess
and the nested function onReaderSuccess
get invoked. The promise is rejected with an error if either the onUrlError
function or onReaderError
function get invoked.
Usage
var countPromise = countDirPromise(cordova.file.dataDirectory +'/Images/');
console.log('Hello ');
countPromise.then(function onSuccess(count) {
console.log('Count of directory '+count);
//return to chain data
return count;
}).catch(function onReject(err) {
console.log(err);
//throw to chain rejection
throw err;
}).then(anotherSuccessFn, anotherRejectFn);
The functions furnished to both the .then
and .catch
methods are invoked asynchronously by the $q
service.
For more information, see AngularJS $q
Service API Reference -- The Deferred API
Using ngCordova
The alternative approach is to use the $q
service promises returned by the ngCordova $cordovaFile API.
function countDirPromise(path){
var count = 0;
console.log('Counting the files inside '+path);
var promise = $cordovaFile.checkDir(path);
var derivedPromise = promise.then(
function onSuccess(fileSystem) {
var q = $q.defer()
var reader = fileSystem.createReader();
reader.readEntries(
function onReaderSuccess(entries) {
var i;
for (i=0; i<entries.length; i++) {
console.log('File name ' + entries[i].name + ' added to count');
count++;
}
//resolve with count
q.resolve(count);
},
function onReaderError(err) {
console.log(err);
//reject with error
q.reject(err);
}
);
//return to chain promise
return q.promise;
};
});
return derivedPromise;
}
You can pass callback to countDir function and call it after the for loop.
var count = countDir(cordova.file.dataDirectory +'/Images/', function(count){
console.log('Hello ');
console.log('Count of directory '+count);
});
And in the definition of the function.
function countDir(path, callback){
...
for (i=0; i<entries.length; i++) {
...
}
callback(count);
...
}
本文标签: javascriptIs Ionic Framework resolveLocalFileSystemURL AsynchronousStack Overflow
版权声明:本文标题:javascript - Is Ionic Framework resolveLocalFileSystemURL Asynchronous? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1745440627a2658432.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论