下面是一个简单的递归函数,它接受一个长度,并使用setTimeout
递减它。一旦长度为<=
0,就完成了。
如何编写此函数(在纯JavaScript中),以便我可以像这样使用它:
animate(999).then(...)
const animate = length => {
console.log(length)
length -= 10
if (length <= 0) {
length = 0
return
}
setTimeout(() => {animate(length)}, 10)
}
animate(999)
&#13;
更新
这是我尝试过的。我遇到的问题是,resolve
似乎没有被调用,或被调用不同的承诺。
const animate = length => {
return new Promise((resolve, reject) => {
console.log(length)
length -= 10
if (length <= 0) {
length = 0
resolve(true)
return // without this the function runs forever
}
setTimeout(() => {animate(length)}, 10)
})
}
animate(999).then(result => console.log(result))
&#13;
**工作更新(但不了解)**
const animate = length => {
return new Promise((resolve, reject) => {
console.log(length)
length -= 10
if (length <= 0) {
length = 0
return resolve(true)
}
setTimeout(() => {resolve(animate(length))}, 10)
})
}
animate(999).then(result => console.log(result))
&#13;
答案 0 :(得分:4)
setTimeout(() => {animate(length)}, 10)
不起作用,这可能会再次调用animate
函数,但永远不会解析在最外层调用中创建的承诺(这就是你的&#34;工作更新&#34;修复 - 它使用递归调用的promise来解析外部promise,这将导致它们以相同的结果实现。)
而不是乱用回调,promisify你正在使用的异步原语,setTimeout
:
function wait(t) {
return new Promise(resolve => {
setTimeout(resolve, t);
});
}
然后在动画函数中使用它来始终返回一个promise:
const animate = length => {
console.log(length)
length -= 10
if (length <= 0) {
length = 0
return Promise.resolve()
}
return wait(10).then(() => {
return animate(length)
})
}
答案 1 :(得分:2)
每次都会生成一个新的Promise
及其resolve
和reject
,因为您在每个Promise
函数调用中都返回一个新的setTimeout
并且只解析最新的一个(if (length <= 0)
内的那个)。
如果您已将Promise((resolve, reject)
放在该功能上,那么它可以正常工作。
或者你随身携带resolve, reject
。
答案 2 :(得分:2)
只是为了好玩,你可以这样做。你不应该。代码超出了无法维护的范围。
const animate = (length, resolve) => {
var promise;
if (!resolve) {
promise = new Promise((newResolve) => {
resolve = newResolve;
});
}
console.log(length);
length -= 10;
if (length <= 0) {
length = 0;
resolve(true);
return promise;
}
setTimeout(() => {animate(length, resolve)}, 10);
return promise;
}
animate(999).then(result => console.log(result))
答案 3 :(得分:1)
async
/ await
:
let wait = ms => new Promise(resolve => setTimeout(resolve, ms));
const animate = async length => {
for (; length > 0; length -= 10) {
console.log(length);
await wait(10);
}
return 0;
}
animate(999).then(() => console.log("Done!"));
&#13;