阅读时间:
12 minutes
文章类型:理论知识 & 案例演示 案例需求:用JavaScript实现,3个小球前后运动,完成接力赛跑 案例源码:见文章最后html
引言:
前端开发中,异步处理必不可少; 过去,咱们常常用回调函数来完成异步处理,所以也常常产生回调地狱(callback hell
); 今天,咱们用实例来对比异步处理的方法; 是时候用async
来处理咱们的异步流程了。前端
Callback
回调函数: 是将一个函数做为参数,传递给另外一个函数,而后在外部函数中调用该函数来完成某种例程或动做。promise
用法:在函数内部调用函数bash
callback
实现小球移动的方法;function move(ele, target, callback) {
let left = parseInt(getComputedStyle(ele)["left"]);
let timer = setInterval(function () {
if (left >= target) {
clearInterval(timer);
callback();
} else {
left += 2;
ele.style.left = left + "px";
}
}, 4)
}
复制代码
move(ball1, 200, function () {
move(ball2, 400, function () {
move(ball3, 600, function () {
alert("callback");
});
})
})
复制代码
Promise
Promise
: 是一个返回值的代理,它容许您将处理程序与异步操做的最终成功值或失败缘由相关联。 这使异步方法能够像同步方法那样返回值:不是当即返回最终值,而是异步方法返回一个Promise
,以便在将来的某个时间点提供该值。异步用法:
Promise
对象是由关键字new
及其构造函数来建立的。该函数接收一个函数(executor function
)做为它的参数。这个函数接受两个函数——resolve
和reject
——做为其参数。当异步任务顺利完成且返回结果值时,会调用resolve
函数;而当异步任务失败且返回失败缘由(一般是一个错误对象)时,会调用reject
函数。async
Promise
实现小球移动的方法;// 让move方法拥有Promise功能
function move(ele, target) {
return new Promise(function (resolve, reject) {
let left = parseInt(getComputedStyle(ele)["left"]);
let timer = setInterval(function () {
if (left >= target) {
clearInterval(timer);
resolve();
} else {
left += 2;
ele.style.left = left + "px";
}
}, 4)
})
}
复制代码
Promise.then()
方法;move(ball1, 200).then(function () {
return move(ball2, 400);
}).then(function () {
return move(ball3, 600);
}).then(function () {
alert("promise");
})
复制代码
Generator
Generator
:生成器函数在函数执行时能暂停,还能从暂停处继续执行,至关于将函数分段执行。函数
用法:必须用
.next()
配合yield
关键字使用;例如: function *gen(){ yield 10; y=yield 'foo'; yield y; } var gen_obj=gen(); console.log(gen_obj.next()); // 执行 yield 10,返回 10 console.log(gen_obj.next()); // 执行 yield 'foo',返回 'foo' console.log(gen_obj.next(10)); // 将 10 赋给上一条 yield 'foo' 的左值,即执行 y=10,返回 10 console.log(gen_obj.next()); // 执行完毕,value 为 undefined,done 为 trueui
Genertor
实现小球移动的方法;// 函数move方法调用上面Promise中的move方法;
function move(ele, target) {
return new Promise(function (resolve, reject) {
let left = parseInt(getComputedStyle(ele)["left"]);
let timer = setInterval(function () {
if (left >= target) {
clearInterval(timer);
resolve();
} else {
left += 2;
ele.style.left = left + "px";
}
}, 4)
})
}
复制代码
let g = m();
g.next(); //让第一个小球运动;
g.next(); //让第二个小球运动;
g.next(); //让第三个小球运动;
复制代码
co
库迭代generator
执行器;function co(it) {
return new Promise(function (resolve, reject) {
function next(d) {
let { value, done } = it.next(d);
if (!done) {
value.then(function (data) {
next(data)
}, reject)
} else {
resolve(value);
}
};
next();
});
}
// 一行代码实现函数执行,可是须要引入co库;
co(m()).then(function () {
alert("generator");
})
复制代码
async/await
async
: 异步函数声明定义了一个异步函数,它返回一个AsyncFunction
对象。当async
函数执行,返回一个Promise
对象;spa用法:用
async
声明函数,函数内配合await
使用。代理
async/await
实现小球移动的方法;// 调用上面的move()方法;
function move(ele, target) {
return new Promise(function (resolve, reject) {
let left = parseInt(getComputedStyle(ele)["left"]);
let timer = setInterval(function () {
if (left >= target) {
clearInterval(timer);
resolve();
} else {
left += 2;
ele.style.left = left + "px";
}
}, 4)
})
}
复制代码
await
方法;async function a() {
await move(ball1, 200);
await move(ball2, 400);
await move(ball3, 600);
}
a().then(function () {
alert("async")
})
复制代码
经过上述4种方法的对比,咱们能够看出
JavaScript
这门语言的发展和进步;ES6+
增长了不少实用功能和方法,将有助于前期代码的编写以及后期代码的维护,是时候用async/await
来处理咱们的异步操做了。
案例源码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
.container .ball {
width: 100px;
height: 100px;
border-radius: 50%;
position: absolute;
}
.container .ball:nth-child(1) {
background-color: blue;
left: 0;
top: 20px;
}
.container .ball:nth-child(2) {
background-color: yellow;
left: 200px;
top: 150px;
}
.container .ball:nth-child(3) {
background-color: green;
left: 400px;
top: 280px;
}
</style>
</head>
<body>
<div class="container">
<div class="ball"></div>
<div class="ball"></div>
<div class="ball"></div>
</div>
<!-- <script src="Promise.js"></script> -->
<script>
let ball = document.querySelectorAll(".ball");
let [ball1, ball2, ball3] = [...ball];
// 1.回调函数处理;
function move(ele, target, callback) {
let left = parseInt(getComputedStyle(ele)["left"]);
let timer = setInterval(function () {
if (left >= target) {
clearInterval(timer);
callback();
} else {
left += 2;
ele.style.left = left + "px";
}
}, 4)
}
move(ball1, 200, function () {
move(ball2, 400, function () {
move(ball3, 600, function () {
alert("callback");
});
})
})
// 2.promise
// generator、async都是基于promise的发展;
// function move(ele, target) {
// return new Promise(function (resolve, reject) {
// let left = parseInt(getComputedStyle(ele)["left"]);
// let timer = setInterval(function () {
// if (left >= target) {
// clearInterval(timer);
// resolve();
// } else {
// left += 2;
// ele.style.left = left + "px";
// }
// }, 4)
// })
// }
// move(ball1, 200).then(function () {
// return move(ball2, 400);
// }).then(function () {
// return move(ball3, 600);
// }).then(function () {
// alert("promise");
// })
// 3.Generator
// function* m() {
// yield move(ball1, 200);
// yield move(ball2, 400);
// yield move(ball3, 600);
// }
// // 利用co方法自动迭代generator
// function co(it) {
// return new Promise(function (resolve, reject) {
// function next(d) {
// let { value, done } = it.next(d);
// if (!done) {
// value.then(function (data) { // 2,txt
// next(data)
// }, reject)
// } else {
// resolve(value);
// }
// }
// next();
// });
// }
// co(m()).then(function () {
// alert("generator");
// })
// 4.async/await
// async function a() {
// await move(ball1, 200);
// await move(ball2, 400);
// await move(ball3, 600);
// }
// a().then(function () {
// alert("async")
// })
</script>
</body>
</html>
复制代码