什么是异步?
异步(Asynchronous, async)
同步(Synchronous, sync)
传统的单线程编程,代码执行依次进行,在主线程来说,是无法接受多方面的请求,因此有时无法快捷迅速回复用户请求。
此时异步就可以用来完成一些耗时长的请求,作为主线程的子线程来说,异步可以处理简单,快速的事件,该子线程独立于主线程,此时就算耗时再长,也不会影响主线程。
但是异步编程要注意一点就是,子线程处理事件何时完成,我们是无法知晓的。
此时引出回调函数来实现该结果的回复处理。
回调函数setTimeout()
开始处理异步单线程,这个函数就会提示该任务,工作完成后该干点其他的啦,这样就可以自主进行。
function print() {
document.getElementById("one").innerHTML="oneeeeee!";
}
setTimeout(print, 1000);//执行之后会产生一个子线程等待 1秒,然后执行回调函数 "print",在命令行输出 "oneeeeee"。
可以用一个更加简洁明了的例子,如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<p>回调函数在1秒后执行</p>
<p id="one"></p>
<p id="two"></p>
<script>
setTimeout(function () {
document.getElementById("one").innerHTML="oneeeeee!";
}, 1000);
document.getElementById("two").innerHTML="twooooo!";
</script>
</body>
</html>
此时可以打开浏览器查看,会发现“twooooo!”首先出现,1秒后"oneeeeee!“出现,这就是异步编程。虽然就代码来看,“one"在前,但是由于它有回调函数,并非主线程,因此它不会妨碍代码主线程后半部分的"two”。
promose
当要处理稍微复杂的多任务,多次顺序执行异步操作的时候;异步就需要promise啦!
比如异步方法先后检测用户名和密码。
Promise 对象:
其中构造函数被称为起始函数,会直接异步执行,其中包含两个参数:esolve 、 reject。
new Promise(function (resolve, reject) {
console.log("hallo");
});
调用 resolve 代表一切正常,反之调用reject。
new Promise
(function (resolve, reject)
{
var a = 100;
var b = 200;
if (b == 0) reject("Divide zero");
else resolve(a / b);
}
).then(function (value)
{
console.log("a / b = " + value);
}
).catch(function (err)
{
console.log(err);
}
).finally(function ()
{
console.log("End");
}
);
其中可以看到.then() .catch() 和 .finally() 三个方法。
这三个方法的参数都是一个函数。
.then() 可以将参数中的函数添加到当前 Promise 的正常执行序列;这里传入的函数依次执行。
.catch() 则是设定 Promise 的异常处理序列;
.finally() 是在 Promise 执行的最后一定会执行的序列。
resolve 和 reject 的作用域只有起始函数,不包括 then 以及其他序列;
resolve 和 reject 无法让起始函数停止运行,利用 return停止。
Promise 函数
该函数用于开发基于异步操作的库。
现在再利用一个“计时器”例子来理异步编程中的“promise”:
function print(delay, message) {
return new Promise(function (resolve, reject) {
setTimeout(function () {
console.log(message);
resolve();
}, delay);
});
}
print(1000, "one").then(function () {
return print(4000, "two");
}).then(function () {
print(3000, "three");
});
resolve() 中放置一个参数用于向 下一个 then传递一个值;
then 中的函数也可以返回一个值传递给 then。
当 then 中返回的是一个 Promise 对象,
那么下一个 then 将相当于对这个返回的** Promise **进行操作。
注意: catch 块只会执行第一个。
异步函数async function()
同样是刚才的计时器例子~
function print(delay, message) {
return new Promise(function (resolve, reject) {
setTimeout(function () {
console.log(message);
resolve();
}, delay);
});
}
async function asyncFunc() {
await print(1000, "one");
await print(4000, "two");
await print(3000, "three");
}
asyncFunc();
可以看出,异步函数 async function 中的 await 指令使用方法:
await 指令后必须跟着一个 Promise!!!
它使得程序代码更加美观,
保持一定时间去完成当前任务,结束后再去做其他的。
再插播个处理异常的机制: try-catch 块:
async function asyncFunc() {
try {
await new Promise(function (resolve, reject) {
throw "Some error"; // 或者 reject("Some error")
});
} catch (err) {
console.log(err);
// 会输出 Some error
}
}
async function asyncFunc() {
let value = await new Promise(
function (resolve, reject) {
resolve("Return value");
}
);
console.log(value);
}
asyncFunc();