Javascript 在Firefox无重启扩展中,使用while循环是一种很好的等待策略吗?

Javascript 在Firefox无重启扩展中,使用while循环是一种很好的等待策略吗?,javascript,sqlite,firefox-addon,firefox-addon-restartless,firefox-addon-bootstrap,Javascript,Sqlite,Firefox Addon,Firefox Addon Restartless,Firefox Addon Bootstrap,我有一个引导扩展,它与Firefox的chrome部分交互(即在内容加载之前),需要进行一些检查。我想要一个同步电话。但是,由于同步调用在性能方面不好,可能会导致UI问题,因此我需要进行异步DB调用 我的用例是这样的: 对数据库进行aysnc调用 完成后,进行进一步处理 现在,将“进一步处理”部分放在executeAsync函数的handleCompletion部分,就可以很容易地处理这个问题 但是,我希望“进一步处理”能够在不考虑执行该语句的情况下完成,即该DB查找可能会发生,也可能不会发

我有一个引导扩展,它与Firefox的chrome部分交互(即在内容加载之前),需要进行一些检查。我想要一个同步电话。但是,由于同步调用在性能方面不好,可能会导致UI问题,因此我需要进行异步DB调用

我的用例是这样的:

  • 对数据库进行aysnc调用
  • 完成后,进行进一步处理
现在,将“进一步处理”部分放在
executeAsync
函数的
handleCompletion
部分,就可以很容易地处理这个问题

但是,我希望“进一步处理”能够在不考虑执行该语句的情况下完成,即该DB查找可能会发生,也可能不会发生。如果事情不顺利,那就去做吧。如果是的话,我需要等待。 因此,我使用的是基于国旗的策略;我在
handleError
handleCompletion
回调中将标记
handleCompletionCalled
设置为
true

在进一步的处理部分,我做了一个

while(handleCompletionCalled) {
 // do nothing
}

//further processing

这是一个好的策略还是我可以做得更好(我真的不想使用观察器等等,因为在我的整个扩展中有很多这样的情况,我的代码中会充满观察器)?

使用
循环等待是一个非常糟糕的主意™. 如果您这样做,结果将是您挂起UI,或者至少通过尽可能快地多次快速运行循环来提高CPU使用率。1

异步编程的要点是启动一个操作,然后在活动完成或失败后执行另一个函数(回调)。这允许您启动多个操作,或者将处理过程放弃给整个代码的其他部分。通常,此回调应该处理依赖于异步操作完成的所有活动。回调函数本身不必包含执行其他处理的代码。在完成异步操作完成后,它可以调用另一个函数,如
doOtherProcessing()

如果启动多个异步操作,则可以通过为每个任务设置标志和在所有不同回调函数末尾调用的单个函数来等待所有操作的完成,如:

function continueAfterAllDone(){
    if(task1Done && task2Done && task3Done && task4Done) {
        //do more processing
    }else{
        //Not done with everything, yet.
        return;
    }
}
这可以通过使用数组或任务队列扩展到任意数量的任务,然后该函数检查这些任务是否全部完成,而不是硬编码的任务集

等待:
如果要执行另一个处理路径,但必须等待异步操作完成,则应通过设置计时器或间隔来执行等待。然后,在指定的时间段内让处理器运行,直到再次检查是否出现了需要继续运行的条件

在引导加载项中,您可能需要使用接口来实现超时或间隔计时器。这是必需的,因为在运行初始化代码时,可能不存在
(即,可能无法访问
窗口。setTimeout()

如果要执行等待其他任务,可以执行以下操作:

const Cc=Components.class;
const Ci=组件。接口;
var asynctasksdone=false;
var otherProcessingDone=false;
//在这里定义计时器,以防我们想在其他地方取消它。
var任务超时器;
函数doStuffSpecificToResultsOfAsyncAction(){
//执行异步操作回调特有的其他操作。
AsyncTaskIsOne=true;
//可以在此处调用DostufAfterOtherTaskCompleteOrInterval(),
//或者等待计时器启动。
DOSTUFAFTERBOTHASYNCDOtherTaskCompleteOrInterval();
}
函数dostufafterbothasyncdonothertaskcompletetesorinterval(){
if(AsyncTaskIsOne&&otherProcessingDone){
if(taskTimeoutTimer.cancel的类型==“函数”){
taskTimeoutTimer.cancel();
}
//任务完成了
}否则{
//未完成的任务。
if(任务超时器){
//计时器已过期。请选择在不执行任何任务的情况下继续
//正在完成,或再次设置计时器。
}
//}else{//如果不想继续等待,请使用else。
taskTimeoutTimer=setTimer(dostufafterbothasyncandothertaskcompletetesorinterval
,5000,假)
//}
}
}
函数setTimer(回调、延迟、isInterval){
//设置超时(.TYPE_ONE_SHOT)或间隔(.TYPE_REPEATING_SLACK)。
让type=Ci.nsimeter.type\u一次
如果(isInterval){
type=Ci.nsimeter.type\u重复\u松弛
}
让timerCallback={
notify:函数notify(){
回调();
}
}
var timer=Cc[“@mozilla.org/timer;1”].createInstance(Ci.nsITimer);
initWithCallback(timerCallback,delay,type);
返回计时器;
}
函数main(){
//启动您正在执行的任何异步操作。
//该操作的回调是doStuffSpecificToResultsOfAsyncAction()。
//执行“其他处理”,这可以在没有异步任务结果的情况下完成。
otherProcessingDone=true;
DOSTUFAFTERBOTHASYNCDOtherTaskCompleteOrInterval();
}
Firefox启动时的初始化代码:
上面的代码是根据我用来延迟一些启动操作的代码修改的,这些操作在显示Firefox UI之前不必执行

在我的一个附加组件中,我有一个合理的处理量,应该完成,但这并不是向用户显示Firefox UI绝对必要的。[参见“”]因此,为了不延迟UI,我使用了计时器和ca