매우 느린 장치 인 경우 실패 할 수있는 setTimeout을 사용하는 대신 카운터를 사용하여 여전히 호출해야하는 콜백 수를 확인할 수 있습니다. 이 테스트 할
var fileSync = new function(){
this.filesystem = null;
this.getFileSystem = function(callback){
var rfs = window.requestFileSystem || window.webkitRequestFileSystem;
rfs(
1// '1' means PERSISTENT
, 0// '0' is about max. storage size: 0==we don't know yet
, function(filesystem){
fileSync.filesystem = filesystem;
callback(filesystem);
}
, function(e){
alert('An error occured while requesting the fileSystem:\n\n'+ e.message);
}
);
}
this.readFilesFromReader = function(reader, callback, recurse, recurseFinishedCallback, recurseCounter)
{
if (recurse && !recurseCounter)
recurseCounter = [1];
reader.readEntries(function(res){
callback(res);
if (recurse)
{
for (var i=0; i<res.length; i++) {
/* only handle directories */
if (res[i].isDirectory == true)
{
recurseCounter[0]++;
fileSync.readFilesFromReader(res[i].createReader(), callback, recurse, recurseFinishedCallback, recurseCounter);
}
}
}
/* W3C specs say: Continue calling readEntries() until an empty array is returned.
* You have to do this because the API might not return all entries in a single call.
* But... Phonegap doesn't seem to accommodate this, and instead always returns the same dir-entries... OMG, an infinite loop is created :-/
*/
//if (res.length)
// fileSync.readFilesFromReader(reader, callback, recurse, recurseFinishedCallback, recurseCounter);
//else
if (recurse && --recurseCounter[0] == 0)
{
recurseFinishedCallback();
}
}
, function(e){
fileSync.onError(e);
if (recurse && --recurseCounter[0] == 0)
recurseFinishedCallback();
});
};
this.onError = function(e){
utils.log('onError in fileSync: ' + JSON.stringify(e));
if (utils.isDebugEnvironment())
alert('onError in fileSync: '+JSON.stringify(e));
}
}
var utils = new function(){
this.log = function(){
for (var i=0;i<arguments.length;i++)
console.log(arguments[i]);
}
this.isDebugEnvironment = function(){ return true }// simplified
}
예제 코드 : 카운터가 0에 도달하면, 당신은이 모든 재귀 코드
: 완료
var myFiles = [];
var directoryCount = 0;
window.onerror = function(){ alert('window.onerror=\n\n' + arguments.join('\n')) }
var gotFilesCallback = function(entries)
{
for (var i=0;i<entries.length;i++)
{
if (entries[i].isFile == true)
myFiles.push(entries[i].fullPath)
else
++directoryCount;
}
}
var allDoneCallback = function(){
alert('All files and directories were read.\nWe found '+myFiles.length+' files and '+directoryCount+' directories, shown on-screen now...');
var div = document.createElement('div');
div.innerHTML = '<div style="border: 1px solid red; position: absolute;top:10px;left:10%;width:80%; background: #eee;">'
+ '<b>Filesystem root:</b><i>' + fileSync.filesystem.root.fullPath + '</i><br><br>'
+ myFiles.join('<br>').split(fileSync.filesystem.root.fullPath).join('')
+ '</div>';
document.body.appendChild(div);
}
/* on-device-ready/on-load, get the filesystem, and start reading files */
var docReadyEvent = window.cordova ? 'deviceready':'load';
document.addEventListener(docReadyEvent, function()
{
fileSync.getFileSystem(function(filesystem){
var rootDirReader = filesystem.root.createReader();
fileSync.readFilesFromReader(rootDirReader, gotFilesCallback, true, allDoneCallback);
})
}, false);
이 방법이하는 일을, 그래서 +1 그에 대한. millisecondsBetweenReadSuccess를 5000으로 설정하고 weAreDone()은 한 번만 호출됩니다. 4000으로 설정하면 두 번 호출됩니다. 나는 다른 장치에서이 코드를 사용하면 작동하지 않을 수 있기 때문에 시간에 민감한 함수를 사용하지 않기를 바랬다 (millisecondsBetweenReadSuccess가 더 커야 할 수도 있음). 더 나은 해결책을 찾지 못하면 귀하의 것을 받아 들일 것입니다. 좀 더 우아한 해결책을 찾으면 여기에 올릴 것입니다. – vdelricco
와우, 5 초가 길다. 나는 당신을 위해 이것을 조금만 수정하려고 그렇게 긴 시간 제한을 갖지 않을 것입니다. 당신은 내가 그것을 필요로하기 전에 나의 생각을 확인함으로써 나를 돕고 있습니다. 흥미롭게도 –
에 대해 for 루프 내에 여분의 if 문을두면 weAreDone 함수가 두 번 호출됩니다 (여전히 5 초로 설정 됨). – vdelricco