我正在开发一个Phonegap应用程序,该应用程序依赖于将不同文本文件中的多个值加载到应用程序中,然后才能正常运行。我认为我正在使用回调函数来解决JS的异步性质,但我程序的输出告诉我代码是以相反的顺序调用的......
在这段代码中,我已经设置了一个唤醒时间 - 它也设置了就寝时间 - 并将两个值保存到文本文件中。
电话的顺序应该是这样的:
Determine if the user is a new user or not... output is not necessary for other parts of application
Determine if the user has entered a waketime in the application before, if so read that time from the relevant text file, if not then use default wake & sleep time
Once we have the correct wake & sleep times, clear all previous notifications from notification queue
Once all previous notifications have been cleared, add new notifications for the current day within the time between waketime and bedtime... this is dependent on the bedtime and waketime already being determined
Concatenate all of the notification times generated into a string
Write this concatenated string to a text file
相关的Javascript变量初始化:
var defaultWakeTime = moment().hours(8).minutes(0).seconds(0);
var defaultBedTime = moment().hours(23).minutes(0).seconds(0);
//variables used to determine notification beginning and end range:
var wakeTimeDate;
var bedTimeDate;
onDeviceReady()中的:
function onDeviceReady() {
console.log("WITHIN onDeviceReady()");
document.addEventListener("pause", userHasGoneIdle , false);
document.addEventListener("backbutton", onBackKeyDown, false);
determineWhichLogin();
determineWakeTimeBedTime(clearPriorNotifications(addNewNotifications));
formNotificationString(writeToNotificationFile);
}
功能代码:
function determineWakeTimeBedTime(callback){
exists('wakeTimeBedTime.txt', function(value){
if(value){
console.log("wakeTimeBedTime.txt found");
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function(fs){
fs.root.getFile('wakeTimeBedTime.txt', null, function(fe){
fe.file(function(file){
var tempReader = new FileReader();
var content;
var lines = [];
tempReader.onloadend = function(evt){
content = evt.target.result;
lines = content.split(/\r\n|\r|\n/g);
console.log(lines[0] + '\n' + lines[1]);
wakeTimeDate = moment(lines[0]);
bedTimeDate = moment(lines[1]);
}
tempReader.readAsText(file);
}, onFSError);
}, onFSError);
}, onFSError);
}
else{
console.log("wakeTimeBedTime.txt NOT found");
bedTimeDate = defaultBedTime;
wakeTimeDate = defaultWakeTime;
}
//Once we've defined bedTimeDate & wakeTimeDate, it's time to create the notifications
if (typeof callback === "function"){
callback();
}
})
}
function clearPriorNotifications(callback){
window.plugin.notification.local.cancelAll();
if (typeof callback === "function"){
callback();
}
}
function addNewNotifications(){
now = moment();
setPartitionNotificationsForDay(now.toDate(), notificationCheckAndAdd);
console.log('notificationCount: ' + notificationCount.toString());
}
function formNotificationString(callback){
var concatString='';
for(var i = 0; i < notificationTimes.length; i++){
concatString += notificationTimes[i].toDate();
concatString += '\n';
}
if(typeof(callback) === 'function'){
callback(concatString);
}
}
function writeToNotificationFile(passedString){
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function(fileSystem){
fileSystem.root.getFile("notification.txt", {create: true, exclusive: false}, function(fileEntry){
//console.log("FILEENTRY.NAME: " + fileEntry);
fileEntry.createWriter(function(writer){
notificationFileWriter = writer;
notificationFileWriter.seek(writer.length);
//console.log('within notificationfile createwriter()');
notificationFileWriter.write(passedString);
notificationFileWriter.onwriteend = function(evt){
//alert(evt);
//console.log("Done writing to notification.txt!");
console.log('notification written: ' + passedString);
}
},onFSError);
},onFSError);
}, onFSError);
}
addNewNotifications()中的函数:
function setPartitionNotificationsForDay(passedDate, callback){
var partitionAmt = (bedTimeDate.toDate() - wakeTimeDate.toDate()) / surveysInADay;
partitionaAmt = Math.round(Math.abs(partitionAmt));
//console.log("Partition amount: " + partitionAmt);
didMissNotificationArr = [];
notificationTimes = [];
var oldMoment = moment(passedDate).hours(wakeTimeDate.hours()).minutes(wakeTimeDate.minutes());
var newMoment = moment(oldMoment).add('milliseconds', partitionAmt);
var randMoment;
var bufferedOldMoment, bufferedNewMoment;
for(var i = 0; i < surveysInADay; i++){
bufferedOldMoment = oldMoment.clone().add('minutes', bufferMins);
bufferedNewMoment = newMoment.clone().subtract('minutes', bufferMins)
randMoment = randomMoment(bufferedOldMoment, bufferedNewMoment);
notificationTimes.push(randMoment);
didMissNotificationArr.push(true);
oldMoment = newMoment;
newMoment = moment(newMoment);
newMoment.add('milliseconds', partitionAmt);
}
if (typeof(callback) === 'function'){
callback();
}
}
//traverse notificationtimes, for all times that are greater than the current time,
//add notificaitons at those times
function notificationCheckAndAdd(callback){
var tempMoment;
var now = moment();
//console.log("Within notificationCheckAndAdd()");
notificationCount = 0;
notificationsToday = 0;
for(var i = 0; i < notificationTimes.length; i++){
tempMoment = moment(notificationTimes[i]);
if(tempMoment.isAfter(now)){
notificationCount += 1;
notificationsToday += 1;
//console.log('Should add notification ' + notificationCount + ' at: ' + tempDate.toShortTimeString());
addNotificationAtTime(tempMoment.toDate(), notificationCount);
//break;
}
}
//I dont really use the callback function within notificationCheckAndAdd
if(typeof(callback) === 'function'){
callback();
}
}
调试输出:
02-26 19:57:30.702: I/chromium(14683): [INFO:CONSOLE(902)] "WITHIN onDeviceReady()", source: file:///android_asset/www/index.html (902)
02-26 19:57:30.722: I/chromium(14683): [INFO:CONSOLE(1810)] "Uncaught TypeError: Cannot call method 'toDate' of undefined", source: file:///android_asset/www/index.html (1810)
02-26 19:57:30.812: I/chromium(14683): [INFO:CONSOLE(1966)] "
02-26 19:57:30.812: I/chromium(14683): oncancel() has been triggered id: 1", source: file:///android_asset/www/index.html (1966)
所以我从中可以看出,在DetermWakeTimeBedTime()完成它的操作之前调用addNewNotifications(),因为determineWakeTimeBedTime()分配变量wakeTimeDate和bedTimeDate,并且它们未定义的唯一方法是addNewNotifications ()在determineWakeTimeBedTime()...
之前开始执行如何重构我的代码以便我可以获得可靠的同步操作?
这是我用来更好地理解回调函数的教程: JS Callback tutorial
在从addNewNotifications()执行代码后,也会调用cancel,并且在DetermBedtimeWaketime()中也不会发生日志语句...所以看起来它正好发生在我身上。
答案 0 :(得分:2)
工作jsfiddle: http://jsfiddle.net/28Uuj/17/
打开您的Web检查器并刷新,debugger;
语句将使您进入调试器,这样您就可以看到每个函数调用的内容。将鼠标悬停在调试时传递给每个函数的回调参数中,你会看到这个难题在你眼前解开! :)
代码本身:
// What you actually want
// Wrap the function2 call inside an
// anonymous function, so the interpeter doesn't try to evaluate it right away
console.log('What you actually want');
function1(function(){ function2(function3) });
// prints:
// What you actually want (index):22
// function1 (index):32
// function2 (index):39
// function3
// The way you have it now
// The interpreter thinks you want to
// evaluate function2(function3) and then pass the RETURN value
// of that into function1
console.log('The way you have it now');
function1(function2(function3));
// prints:
// The way you have it now (index):26
// function2 (index):39
// function3 (index):46
// function1 (index):32
// Uncaught TypeError: undefined is not a function (index):3
function function1(callback)
{
debugger;
console.log('function1');
callback();
}
function function2(callback)
{
debugger;
console.log('function2');
callback();
}
function function3()
{
debugger;
console.log('function3');
}