在Javascript中查询本地值的首选方法是什么?

例如,有一个名为animationComplete的variables(来自第三方库)和一个名为happenAfterAnimation的函数:

一个简单的解决scheme如下所示:

 while(!animationComplete) { // Do nothing } happenAfterAnimation() 

或者像这样一个更复杂的解决scheme:

 function tryHappenAfterAnimation() { if(animationComplete) { happenAfterAnimation() } else { setTimeout(tryHappenAfterAnimation, 100) } } setTimeout(tryHappenAfterAnimation, 100) 

第一个解决scheme可能有一些开销,第二个解决scheme看起来有点脏。

由于future/promise是不是在当前版本的Javascript中可用,它的方式可能有点矫枉过正这里..我只是想知道是否有一个优雅和轻量级的方式来处理这种情况..

有没有人有更好的方式来处理这个想法? 谢谢!

第一种方法根本行不通。 它会永远阻塞线程。

没有内置的承诺支持并不是真正的借口不使用承诺。 如果你的图书馆给你一个事件/callback驱动的方式来等待结果(如果没有,我会感到惊讶),那么你应该使用一个事件或承诺。

如果没有,并且查询variables真的是你唯一的select,那么我会说你的第二种方法几乎是唯一的select。

快速总结 – 你的第一个方法将无法工作(这将只是一个无限循环)和轮询机制(虽然它可以使工作)从来没有“首选”的select。

Javascript是单线程的(有一些例外,比如webWorkers,但是它们在这里不适用),只要你的while循环运行,没有其他JS可以运行,可能会改变animationComplete的值,所以你会有一个无限循环将永远不会完成(最终浏览器会抱怨JS线程还没有完成,并提供给用户停止脚本的机会)。

知道animation完成的正确方法是使用callback来完成animation。 如果你使用的是jQuery,那么所有的jQueryanimation都有一个完成callback,你可以传递它,当animation完成时它会被调用。 然后,您将在callback函数中的animation后发生的代码。

如果您正在使用CSS3animation,则可以为transitionend事件注册一个事件处理程序,并在animation完成时以这种方式获取callback。

如果你想轮询一个variables的值,那么使用一个计时器轮询它将是一个合适的select,因为这允许其他代码运行,实际上可以改变variables。

我应该补充说,这样的投票很less是最好的deviseselect。 如果它是一个animation,那么你只是想在animation上使用一个完成事件,所以不需要轮询。 如果出于某种原因,您正在使用一个没有内置完成事件的animation函数,那么可能需要修改该代码来包含这样一个callback,因为它总是可能的,而且显然是有用的。


为了提供更详细的build议,我们需要更多地了解animation代码以及您正在尝试做什么。 正如我之前所说,所有的jQueryanimation提供承诺和callback支持完成通知(你没有标记问题jQuery是为什么我提到)。

在任何接口中缺乏承诺并不是不使用完成callback的原因,因此事实在这里没有真正的相关性,并且任何给定的函数也可以被普遍化(如果承诺是期望的方式,则将简单的callback变成承诺接口)与asynchronous事件交互。

这是一个基于Promise的方法。 以下实现定期轮询和超时。

 var Promise = require('bluebird'); /** * Periodically poll a signal function until either it returns true or a timeout is reached. * * @param signal function that returns true when the polled operation is complete * @param interval time interval between polls in milliseconds * @param timeout period of time before giving up on polling * @returns true if the signal function returned true, false if the operation timed out */ function poll(signal, interval, timeout) { function pollRecursive() { return signal() ? Promise.resolve(true) : Promise.delay(interval).then(pollRecursive); } return pollRecursive() .cancellable() .timeout(timeout) .catch(Promise.TimeoutError, Promise.CancellationError,function () { return false; }); } 

你这样称呼。

 poll(animationComplete, pollingInterval, timeout) .then(function(complete) { if (complete) happenAfterAnimation(); } ); 

请参阅承诺的Javascript轮询 。