我有一个函数foo,我想添加一个睡眠/等待函数来制作一种DOM元素动画.我已经做了一些研究,我知道暂停一个javascript函数是不可能的,因为它会冻结浏览器 - 如果我错了,请纠正我.我怎么能克服它?
function foo() {
while (someCondition) {
var $someDiv = $('.someDiv:nth-child(' + guess + ')');
$someDiv.css({'background-color': 'red'});
wait 1000ms
$someDiv.css({'background-color': 'blue'});
wait 1000ms
if (someCondition2) {
doSomething; }
else {
for loop }
}
}
Run Code Online (Sandbox Code Playgroud)
$someDiv每个while循环迭代引用不同的DOM元素,因为变量guess变化
我试过的
我使用下面的函数,它工作但问题是我无法for在我的异步函数foo中使用循环
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
Run Code Online (Sandbox Code Playgroud)我试过,setTimeout但我无法取得任何有效的结果.
如果我将setTimeout这段代码包装起来:
('$someDiv').css({'background-color': 'red'});那么在指定的时间之后,所有的$someDiv'scss样式都会一起改变(请记住,$someDiv每次while循环迭代都会引用不同的DOM元素).
如果我用setTimeout一个代码包装if,else语句然后我有一个错误 - 无限循环
题
简化foo功能只是为了可视化问题.我正在处理的原始函数可以在codepen(findNumber函数)上找到
我想制作二进制搜索算法动画.同样的事情也来此
我怎样才能达到预期的效果?
一般情况下:如何在循环中为DOM元素设置动画,每次迭代之间有间隔?
解决这个问题的最好、最干净的解决方案是使用未来版本的 Javascript (ES2017) 中的async/await功能。这可以让你摆脱回调地狱。您可以创建一个sleep如下所示的简单函数:
function sleep(time) {
return new Promise(resolve => setTimeout(()=>resolve(), time));
}
Run Code Online (Sandbox Code Playgroud)
您可以通过正常处理来使用它Promise:
sleep(1000).then(()=>console.log('A second later'));
Run Code Online (Sandbox Code Playgroud)
但是,通过该async功能,您可以使用await关键字使代码等待 Promise 解决后再继续。
async function doSomething() {
await sleep(1000);
console.log('A second later');
}
Run Code Online (Sandbox Code Playgroud)
这意味着您也可以使用普通循环,包括breakandcontinue语句:
async function doSomething() {
let i = 0;
while (true) {
await sleep(1000);
console.log(i);
if (++i === 5) break;
}
}
Run Code Online (Sandbox Code Playgroud)
这意味着您的代码可以大大简化:
async function foo() {
var n = 5;
while (n > 0) {
n--;
var wait = 0;
//$('#someDiv').css({'background-color': 'red'});
console.log('doSomething-1');
//wait 1000ms
await sleep(1000);
//$('#someDiv').css({'background-color': 'blue'});
console.log('doSomething-2');
//wait 1000ms
await sleep(1000);
if (true) {
console.log('doSomething-3');
break;
} else {
console.log('loop')
}
}
}
Run Code Online (Sandbox Code Playgroud)
( jsFiddle )
唯一的问题是该功能远未得到普遍支持。因此,您需要使用Babel等软件对其进行转译。
另请注意,在幕后,您的foo函数现在立即返回并给出一个Promise. 这Promise是通过函数的返回值来解决的。因此,如果您想在完成后执行更多代码foo,则必须执行foo().then(/*callback*/).
| 归档时间: |
|
| 查看次数: |
121 次 |
| 最近记录: |