JavaScript异步编程与Promise

JavaScript异步编程

异步

异步(async)是与同步相对的概念。传统的单线程编程中,程序的运行是同步的。同步并不意味着所有的步骤同时运行,而是指步骤在一个控制流中顺序执行。而异步相反,不保证同步,一个异步过程的执行不再与原有的序列有顺序关系。

简单来说,你的代码顺序是什么样,同步就按顺序来;而异步不按顺序来,从主线程发送一个子线程完成任务效率更高。如下图所示:
在这里插入图片描述
主线程是单一线程,不能同时接受多方面的请求,所以当一个事件没有结束时,无法同时处理其他请求。因此我们常常用子线程来完成一些可能消耗时间长、以至于被用户所察觉的事件,比如读取一个大文件或者发出一个网络请求。

子线程特点:

  1. 独立于主线程,即使出现堵塞也不会影响主线程的运行;
  2. 一旦发射之后就与主线程失去同步,无法确定结束事件,无法处理结束之后需要进行的一系列操作。例如来自服务器的信息,我们无法将其合并到主线程中去。

回调函数

由于子线程的一系列特性,JavaScript的异步操作通常通过回调函数实现异步任务的结果处理。
比如当我们启动一个异步任务时,告诉子线程完成这个任务之后该做什么。如此一来,主线程就不用关心异步任务的状态。

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title></title>
</head>
<body>

<p>回调函数等待 3 秒后执行。</p>
<p id="demo"></p>
<script>
    function print() {
        document.getElementById("demo").innerHTML="learn more!";
    }
    setTimeout(print, 3000);
</script>

</body>
</html>

该段程序主线程运行第一个p标签内容等,子线程运行setTimeout,是一个消耗时长三秒的过程,第一个参数时回调函数,第二个参数是毫秒数。子线程等待三秒后执行回调函数print,命令行输出learn more!

需要注意的是:在setTimeout执行之后,主线程并没有停止!!

AJAX

AJAX:Asynchronous JavaScript and XML(异步的 JavaScript 和 XML)
AJAX是一种使用现有标准的新方法,可以在不重新加载整个页面的情况下,与服务器交换数据并异步更新部分网页内容。
在这里插入图片描述
占坑补充。。。。。。

JavaScript Promise

Promise是ES6提供的类,目的是更加优雅的书写复杂的异步任务。

新建Promise

new Promise(function(resolve, reject){
       //to do
});

对于多次调用异步函数,如第一次间隔1秒,第二次间隔4秒,第三次间隔3秒:

setTimeout(function () {
    console.log("First");
    setTimeout(function () {
        console.log("Second");
        setTimeout(function () {
            console.log("Third");
        }, 3000);
    }, 4000);
}, 1000);

以上程序看起来十分累赘,对于更加复杂的异步程序而言就变得更加繁琐了。使用Promise实现同样的功能:

new Promise(function (resolve, reject) {
    setTimeout(function () {
        console.log("First");
        resolve();
    }, 1000);
}).then(function () {
    return new Promise(function (resolve, reject) {
        setTimeout(function () {
            console.log("Second");
            resolve();
        }, 4000);
    });
}).then(function () {
    setTimeout(function () {
        console.log("Third");
    }, 3000);
});

Promise的使用

new Promise(function(resolve, reject){
       //to do
});

Promise构造函数只有一个参数,是一个函数。这个函数在构造之后会被异步执行,称为起始函数。它包含两个参数,resolvereject,调用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");
});

输出结果为:

a / b = 0
End

Promise类有三个方法,它们的参数都是一个函数:

  1. .then()可以将自己参数中的函数添加到当前Promise的正常执行序列,其传入的参数会按顺序依次执行,有任何异常都会跳到catch序列;
  2. .catch()设定Promise的异常处理序列;
  3. .finally()在Promise执行最后一定会执行的序列。

实例

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;reject()传递一个异常给之后的catch函数处理异常。
注意:

  1. resolve 和 reject 的作用域只有起始函数,不包括 then 以及其他序列;
  2. resolve 和 reject 并不能够使起始函数停止运行,别忘了 return;
  3. then 块默认会向下顺序执行,return 是不能中断的,可以通过 throw 来跳转至 catch 实现中断。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

eynoZzzzc

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值