目录

什么是异步?

什么时候用异步编程

回调函数

Promise 的使用

.then() .catch() 和 .finally() 三个方法


什么是异步?

异步与同步是相反的

简单来理解就是:同步按你的代码顺序执行,异步不按照代码顺序执行,异步的执行效率更高。

什么时候用异步编程

在前端编程中(甚至后端有时也是这样),我们在处理一些简短、快速的操作时,例如计算 1 + 1 的结果,往往在主线程中就可以完成。主线程作为一个线程,不能够同时接受多方面的请求。所以,当一个事件没有结束时,界面将无法处理其他请求。

现在有一个按钮,如果我们设置它的 onclick 事件为一个死循环,那么当这个按钮按下,整个网页将失去响应。

为了解决类似这种问题,JavaScript 中的异步操作函数往往通过回调函数来实现异步任务的结果处理。

回调函数

回调函数就是一个函数,它是在我们启动一个异步任务的时候就告诉它:等你完成了这个任务之后要干什么。这样一来主线程几乎不用关心异步任务的状态了,他自己会善始善终。

例如:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>回调</title>
</head>
<body>
    <button>点击</button>
    <p></p>
    <script>
        var btn = document.querySelector('button');
        function fn1(){
            btn.onclick = function(){
                document.querySelector('p').innerHTML = '我出现了!'
            }
        }
        setTimeout(fn1,1000)
    </script>
</body>
</html>

 

 它的第一个参数是个回调函数,第二个参数是毫秒数,这个函数执行之后会产生一个子线程,子线程会等待 1 秒,然后执行回调函数 "fn1",在命令行输出 "我出现了!"。

Promise 的使用

Promise有三种状态:pending=>resolved => rejected

语法格式:

new Promise(function (resolve, reject) {
});
        const p1 = new Promise((resolve,rejuct)=>{
            // throw new Error
        })
        console.log(p1);

 

默认状态为pending 

const p1 = new Promise((resolve, rejuct) => {
    resolve();
})
console.log(p1);

 

默认状态为fulfilled等同于resolved

const p1 = new Promise((resolve, rejuct) => {
    rejuct();
})
console.log(p1);

状态为 rejected

resolve和reject是参数 

再看这个例子:

new Promise(function (resolve, reject) {
    var a = 0;
    var b = 1;
    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 执行的最后一定会执行的序列。 .then() 传入的函数会按顺序依次执行,有任何异常都会直接跳到 catch 序列:

new Promise(function (resolve, reject) {
    console.log(1111);
    resolve(2222);
}).then(function (value) {
    console.log(value);
    return 3333;
}).then(function (value) {
    console.log(value);
    throw "An error";
}).catch(function (err) {
    console.log(err);
});

打印结果为:

1111
2222
3333
An error

resolve() 中可以放置一个参数用于向下一个 then 传递一个值,then 中的函数也可以返回一个值传递给 then。但是,如果 then 中返回的是一个 Promise 对象,那么下一个 then 将相当于对这个返回的 Promise 进行操作,这一点从刚才的计时器的例子中可以看出来。

reject() 参数中一般会传递一个异常给之后的 catch 函数用于处理异常。

但是请注意以下两点:

  • resolve 和 reject 的作用域只有起始函数,不包括 then 以及其他序列;
  • resolve 和 reject 并不能够使起始函数停止运行,别忘了 return。

本文转载:CSDN博客