JS异步编程——学习笔记

Javascript语言的执行环境是"单线程"(single thread),所谓"单线程",就是指一次只能完成一件任务。如果有多个任务,就必须排队,前面一个任务完成,再执行后面一个任务,以此类推。这种模式的好处是实现起来比较简单,执行环境相对单纯;坏处是只要有一个任务耗时很长,后面的任务都必须排队等着,会拖延整个程序的执行。常见的浏览器无响应(假死),往往就是因为某一段Javascript代码长时间运行(比如死循环),导致整个页面卡在这个地方,其他任务无法执行。

为了解决这个问题,Javascript语言将任务的执行模式分成两种:同步(Synchronous)和异步(Asynchronous)。

同步模式

就是机械一行一行的执行代码直到代码结束,一旦出现问题就执行不下去了。

异步模式

就是执行到异步代码的时候会将这个代码内容暂时挂起,然后继续执行下面内容,当挂起的内容得到响应的时候,又返回来继续执行这个异步代码之后的内容。

js常见的异步操作有:

  • setTimeout (setInterval)
  • AJAX
  • 事件绑定(如:.on,.bind,.listen,.addEventListener,.observe)
  • 观察者模式(例如:websocket中就有发布和订阅之类的操作)
  • promise 是一个异步操作,但是它是一个异步操作的解决方案,即保存着异步操作的结果,可以把异步函数以同步函数的形式写出来
  • async/await — 使用generator的语法糖,可以理解为是generator的一种改进
  • generator函数 — 使用promise的语法糖,可以理解为是promise的另一种拓展

异步编程解决方案

回调函数

回调函数就是将一个函数当作另一个主函数的参数来使用的函数。

function test2(){//回调函数
    console.log('执行了test2');
}
function test1(callback){ //(主函数)
    console.log('执行了test1');
   setTimeout(function () {
     callback();
   }, 1000);
}
// 执行
test1(test2); 

解读:回调函数是传统的一种异步编程解决方案,其原理就是将一个函数当作参数传递到另一个主函数中,当主函数执行完自身的内容之后,在运行传递进来的回调函数。这样就达成了类似异步的效果。

缺点:一个任务只能有一个回调函数

用法:回调函数在js中用的还是比较多的,例如:jsonp、ajax、一些常见的需要传递函数当参数来处理一些后续内容的操作

回调函数分为异步回调和同步回调,其实区别就在于主函数中是否执行了异步操作而已

promise

Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大,简单地说,Promise好比容器,里面存放着一些未来才会执行完毕(异步)的事件的结果,而这些结果一旦生成是无法改变的

基本使用示例
const promise = new Promise((resolve, reject) => {
    resolve(100)
    // reject(new Error('promise rejected'))  失败
});

promise.then(function (res) {
        return a();
    }).catch(function (e) {
        catchInfo(e);
    })

console.log('end')

Promise((resolve,reject)=>{}),当内部的异步操作完成后就执行resolve,如果出现异常就执行reject即可。resolve对应的是.then()、reject对应的是.catch();

Promise的真正强大之处在于它的多重链式调用,可以避免层层嵌套回调。例如我们在ajax请求后,还要用它返回的结果再次请求,就可以使用Promise,利用then进行「链式回调」,将异步操作以同步操作的流程表示出来。

链式调用示例
let promise = new Promise((resolve, reject) => {
    resolve('999')
})
promise.then((value) => {
    console.log("成功11", value)
    return 100
}).then((value) => {
    console.log("成功22", value)
    return 200
}).then((value) => {
    console.log("成功33", value)
})
async-await

async await也是异步编程的一种解决方案,他遵循的是Generator 函数的语法糖,他拥有内置执行器,不需要额外的调用直接会自动执行并输出结果,它返回的是一个Promise对象。

 async function test() {
    let aa = await aa();
    console.log(aa)
}
Promise和async/await比较

Promise的出现解决了传统callback函数导致的“地域回调”问题,但它的语法导致了它向纵向发展行成了一个回调链,遇到复杂的业务场景,这样的语法显然也是不美观的。而async await代码看起来会简洁些,使得异步代码看起来像同步代码,await的本质是可以提供等同于”同步效果“的等待异步返回能力的语法糖,只有这一句代码执行完,才会执行下一句。

async await与Promise一样,是非阻塞的。

async await是基于Promise实现的,可以说是改良版的Promise,它不能用于普通的回调函数。

你可能感兴趣的:(JS异步编程——学习笔记)