如何在 Promise 中使用 requestAnimationFrame
How to use requestAnimationFrame with Promise
我想在Promise中使用requestAnimationFrame,所以我可以这样使用它
opacityToggle("layername",0).then(i=>"do some stuff after animation ends")
,但不确定如何执行此操作。这是我的代码:
function opacityToggle(layerName, opacity) {
if (!layerName) return;
var requestID;
var s = 0;
return animate().then(i => i)
function animate() {
requestID = requestAnimationFrame(animate);
if (s < 1) {
s += 0.01
s = +s.toFixed(2)
console.log('s', layerName, s, opacity);
map.setPaintProperty(layerName, 'fill-opacity', s);
} else {
cancelAnimationFrame(requestID);
return new Promise(resolve => resolve)
}
}
}
您使 opacityToggle
函数的 return 语句过于复杂。您只需 return 承诺并将所有 RAF 逻辑封装在其中。这应该足够了:
function opacityToggle(layerName, opacity) {
if (!layerName) return;
var requestID;
var s = 0;
return new Promise(resolve => {
// Animation steps
function animate() {
if (s < 1) {
s += 0.01
s = +s.toFixed(2)
console.log('s', layerName, s, opacity);
map.setPaintProperty(layerName, 'fill-opacity', s);
requestID = requestAnimationFrame(animate);
} else {
// If animation is complete, then we resolve the promise
cancelAnimationFrame(requestID);
resolve();
}
}
// Start animation
requestID = requestAnimationFrame(animate);
});
}
虽然你的问题并不清楚你想用什么价值来解决承诺。如果您愿意,可以简单地将其提供为 resolve(yourResolvedValueHere)
。
虽然@Terry 有一个简单的解决方案,可以将所有内容都包装在 promise 构造函数中,但如果您仅对 requestAnimationFrame
调用本身进行 promisify,您将获得 promises 的真正力量:
async function opacityToggle(layerName, opacity) { /*
^^^^^ */
if (!layerName) return;
var s = 0;
while (s < 1) {
// ^^^^^
s += 0.01
s = +s.toFixed(2)
console.log('s', layerName, s, opacity);
map.setPaintProperty(layerName, 'fill-opacity', s);
await new Promise(resolve => {
// ^^^^^
requestAnimationFrame(resolve);
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
});
}
}
如果你不能使用async
/await
and/or想用递归的方法来做,那就是
function opacityToggle(layerName, opacity) {
if (!layerName) return Promise.resolve();
var s = 0;
return animate();
function animate() {
if (s < 1) {
s += 0.01
s = +s.toFixed(2)
console.log('s', layerName, s, opacity);
map.setPaintProperty(layerName, 'fill-opacity', s);
return new Promise(resolve => {
// ^^^^^^
requestAnimationFrame(resolve);
}).then(animate);
// ^^^^^^^^^^^^^^
} else {
return Promise.resolve();
}
}
}
我想在Promise中使用requestAnimationFrame,所以我可以这样使用它
opacityToggle("layername",0).then(i=>"do some stuff after animation ends")
,但不确定如何执行此操作。这是我的代码:
function opacityToggle(layerName, opacity) {
if (!layerName) return;
var requestID;
var s = 0;
return animate().then(i => i)
function animate() {
requestID = requestAnimationFrame(animate);
if (s < 1) {
s += 0.01
s = +s.toFixed(2)
console.log('s', layerName, s, opacity);
map.setPaintProperty(layerName, 'fill-opacity', s);
} else {
cancelAnimationFrame(requestID);
return new Promise(resolve => resolve)
}
}
}
您使 opacityToggle
函数的 return 语句过于复杂。您只需 return 承诺并将所有 RAF 逻辑封装在其中。这应该足够了:
function opacityToggle(layerName, opacity) {
if (!layerName) return;
var requestID;
var s = 0;
return new Promise(resolve => {
// Animation steps
function animate() {
if (s < 1) {
s += 0.01
s = +s.toFixed(2)
console.log('s', layerName, s, opacity);
map.setPaintProperty(layerName, 'fill-opacity', s);
requestID = requestAnimationFrame(animate);
} else {
// If animation is complete, then we resolve the promise
cancelAnimationFrame(requestID);
resolve();
}
}
// Start animation
requestID = requestAnimationFrame(animate);
});
}
虽然你的问题并不清楚你想用什么价值来解决承诺。如果您愿意,可以简单地将其提供为 resolve(yourResolvedValueHere)
。
虽然@Terry 有一个简单的解决方案,可以将所有内容都包装在 promise 构造函数中,但如果您仅对 requestAnimationFrame
调用本身进行 promisify,您将获得 promises 的真正力量:
async function opacityToggle(layerName, opacity) { /*
^^^^^ */
if (!layerName) return;
var s = 0;
while (s < 1) {
// ^^^^^
s += 0.01
s = +s.toFixed(2)
console.log('s', layerName, s, opacity);
map.setPaintProperty(layerName, 'fill-opacity', s);
await new Promise(resolve => {
// ^^^^^
requestAnimationFrame(resolve);
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
});
}
}
如果你不能使用async
/await
and/or想用递归的方法来做,那就是
function opacityToggle(layerName, opacity) {
if (!layerName) return Promise.resolve();
var s = 0;
return animate();
function animate() {
if (s < 1) {
s += 0.01
s = +s.toFixed(2)
console.log('s', layerName, s, opacity);
map.setPaintProperty(layerName, 'fill-opacity', s);
return new Promise(resolve => {
// ^^^^^^
requestAnimationFrame(resolve);
}).then(animate);
// ^^^^^^^^^^^^^^
} else {
return Promise.resolve();
}
}
}