「这是我参与2022首次更文挑战的第29天,活动详情查看:2022首次更文挑战」。
写在前面
- 在前面两篇文章中,我们通过嵌套回掉函数、自定义事件的方式都实现了我们的异步操作
- 但这两种实现方式都或多或少有些不优雅
- 嵌套回掉函数的方式在代码量增多后,会变得极其难以维护,且不能友好阅读代码
- 自定义事件的方式,倒是比较优雅,但是为了区分不同的事件,我们需要引入额外的变量来,标识不同事件
- 接下来,这篇文章将通过社区更加流行的 promise 写法来实现之前的例子
基于 promise 对象的改造
- 同样的我们需要改造 move 函数
- 既然是基于 promise 的,那么 move 函数就需要返回一个 promise 对象
- 下面是具体实现
let move = (ele, direction, target, cb) => {
return new Promise((resolve) => {
let fn = () => {
let start = parseInt(getComputedStyle(ele, null)[direction]);
let speed = ((target - start) / Math.abs(target - start)) * 2;
start += speed;
ele.style[direction] = `${start}px`;
setTimeout(() => {
if (Math.abs(target - start) <= 2) {
ele.style[direction] = `${target}px`;
// cb & cb();
resolve();
} else {
fn();
}
}, 10);
};
fn();
});
};
- 在实例化 promise 对象时,传入一个函数,其接收的则是 resolve 回掉,函数里面是 move 函数的具体处理逻辑
- 同样的,获取 dom 元素样式,以及设置 dom 元素的样式,的方式依然不变
- 不同的是,执行 cb 回掉函数的代码换成了 resolve 回掉
- 表示当 dom 元素运动到终点时,就会 resolve 掉,否则继续调用 move 函数的主处理逻辑
- 接下来看看如何使用 move 函数的
// move(ele, "left", 301, () => {
// console.log("右移 ok");
// move(ele, "top", 301, () => {
// console.log("下移 ok");
// move(ele, "left", 0, () => {
// console.log("左移 ok");
// move(ele, "top", 0, () => {
// console.log("上移 ok");
// });
// });
// });
// });
// promise改造:链式调用;
move(ele, "left", 300)
.then(() => {
return move(ele, "top", 300);
})
.then(() => {
return move(ele, "left", 0);
})
.then(() => {
return move(ele, "top", 0);
})
.then(() => {
console.log("完成");
});
- 有了 promise 对象,那么我们就可以直接使用 then 方法了
- 当前面的 promise 对象被 resolve 掉时,then 方法里面的回掉函数就会被执行,我们只用在回掉中调用 move 方法即可
小结
- 至此,我们已经使用了三种方式去实现我们的异步操作了
- 尽管 promise 的使用,让我们的代码,避免了嵌套回掉函数,避免了自定义事件引入额外变量
- 但是当我们的操作步骤很多时,promise 的链式调用也会很长,多少有些不优雅
- 那么有没有更佳,优雅的实现方式呢?
- 下篇文章,我们将使用 async-await 去实现上面的例子
最后
- 今天的分享就到这里了,欢迎大家在评论区里面进行讨论 👏。
- 如果觉得文章写的不错的话,希望大家不要吝惜点赞,大家的鼓励是我分享的最大动力 🥰