js异步编程一:同步异步模式的区别,回调函数和 Promise基本用法

javascript都是采用单线程模式工作的原因与它最早的设计初衷有关,最早javascript这门语言就是运行在浏览器端的脚本语言,目的是为了实现页面上的动态交互,而实现页面交互的核心是DOM操作,所以就决定了必须是单线程模型,否则就会出现很复杂的线程同步问题。

如果在javascript中有多个线程同时工作,那其中一个线程修改了某个DOM元素,且另外一个线程同时又删除了这个元素,那DOM就无法确定以哪个线程为准,所以为了避免线程同步的问题,从一开始javascript就被设计成单线程操作。

Javascript的单线程指的是在JS执行环境中负责执行代码的线程只有一个,这种更安全更简单,但缺点也同样很明显,如果遇到一个特别耗时的任务,那后面的任务都必须去排队等待这个任务的结束,会导致整个运行被拖延,出现假死的情况,为了解决这个问题,javascript将任务的执行模式分成了两种,分别是同步模式(Synchronous)和异步模式(Asynchronous)

同步模式
执行的时候压入调用盏中,会记录当前正在执行的任务,执行完从盏中消失,当有一个任务耗时很长时,后面的任务容易阻塞。单线程的javascript语言无法同时处理大量耗时的任务

异步模式
异步模式不会去等待这个任务的结束才开始下一个任务,对于耗时的任务,都是开启过后就立即往后执行下一个任务,后续的逻辑一般会通过回调函数的方式定义,在这个耗时任务完成过后就会自动执行回调函数。

在这里插入图片描述
webAPIs内容api的环境,以web环境举例所以是web api
Eventloop事件循环
queue消息队列(回调队列)
Call stack调用盏
anonymous匿名的全局调用
在这里插入图片描述
负责监听调用盏和消息队列,一但调用盏中的任务都结束了,事件循环就会从消息队列中取第一个回调函数,然后压入到调用盏,只不过此时消息队列中是空的,执行就相当于暂停下来,webapi中倒计时过后就会被放到queue消息队列中的。
在这里插入图片描述
javascript是单线程的,但浏览器不是单线程的,通过调 用javascript的某些api并不是单线程的,例如倒计时器,它内部有一个单独的线程去负责倒数,时间到了过后会将回调放入到消息队列,也就是说这样的一件事情是有一个单独的线程去做的。我们说的单线程是指执行的代码的线程。而运行的环境提供的API是以同步或异步模式的方式工作。

回调函数
是所有异步编程方案的根基,回调函数可以理解为一件你想要做的事情,但是你不知道你依赖的任务什么时候能完成,就直接把这个步骤给执行者让它去执行,这个步骤就是回调函数。由调用者定义,交给执行者执行的函数。
在这里插入图片描述
Promise概述(Promise是一种更优的异步编程统一方案。)
直接使用传统回调方式去完成复杂的异步流程,就无法完成大量的复杂的函数嵌套,比如下图
在这里插入图片描述
所以CommnJS社区提出了Promise的规范,在ES2015中被标准化,成为语言规范,Promise是一个对象,用来表示一个异步任务,返回最终承诺的成功或失败的结果,不管这个承诺成功或失败都有相应的反应,在承诺状态最终明确了过后,都会有相对应的任务自动执行。
在这里插入图片描述
Promise基本用法

const promise = new Promise(function (resolve, reject) {
  //这里用于“兑现”承诺
  resolve(200); //承诺达成

  // reject(new Error("promise rejected")); //承诺失败
});
promise.then(
  function (value) {
    console.log("resolved", value);
  },
  function (err) {
    console.log("rejected", err);
  }
);

Promise使用案例(用Promise去封装ajax请求的例子)

function ajax(url) {
  return new Promise(function (resolve, reject) {
    var xhr = new XMLHttpRequest();
    xhr.open("GET", url);
    xhr.responseType = "json";
    xhr.onload = function () {
      if (this.status == 200) {
        resolve(this.response);
      } else {
        reject(new Error(this.statusText));
      }
    };
    xhr.send();
  });
}
ajax("/api/user.json").then(
  function (res) {
    console.log(res);
  },
  function (error) {
    console.log(error);
  }
);

Promise常见误区
Promise的本质上也是使用回调函数,定义的异步任务结束后所需要执行的任务,只不过这里的回调函数是通过then方法传递进去的,而且promise将回调分成了两种,成功过后的回调 onFulfilled和失败过后的回调 onRejected,如果需要串连多个任务的时候,仍然会出现函数回调嵌套的问题
在这里插入图片描述
这种嵌套使用的方式是使用Promise最常见的错误,应借助于Promise then方法链式调 用的特点,尽量能保证异步任务的扁平化

  • 5
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值