一、

1、异步(async)

异步,它的孪生兄弟--同步(Synchronous),"同步模式"就是上一段的模式,后一个任务等待前一个任务结束,然后再执行,程序的执行顺序与任务的排列顺序是一致的、同步的.

"异步模式"则完全不同,每一个任务有一个或多个回调函数(callback),前一个任务结束后,不是执行后一个任务,而是执行回调函数,后一个任务则是不等前一个任务结束就执行,所以程序的执行顺序与任务的排列顺序是不一致的、异步的。 "异步模式"非常重要。在浏览器端,耗时很长的操作都应该异步执行,避免浏览器失去响应,最好的例子就是Ajax操作。就现在来说应该没有什么后台服务器还是同步操作了...

用最直观的代码来体现:

 <body>
<button id="Button">展示异步操作</button>
<script>
var Button=document.getElementById('Button');
Button.onclick=function(){
alert('展示异步操作--a');
}
alert('展示异步操作--b');
</script>
</body>

这个简单的例子就体现出了异步和同步的区别了:

我们平常写的代码,都是从上到下来执行的,一般上面的语句还没有执行结束的情况下,下面的语句是不会执行的,但是这段代码我们很容易测试出:先弹出b窗口,当你点击按钮的时候才开始弹出a窗口。 这就是典型的异步操作,不用等把上面的语句全部执行完才开始执行下面的语句。

2、Promise

Javascript 采用回调函数(callback)来处理异步编程。从同步编程到异步回调编程有一个适应的过程,但是如果出现多层回调嵌套,也就是我们常说的厄运的回调金字塔(Pyramid of Doom),绝对是一种糟糕的编程体验。于是便有了 CommonJS 的 Promises/A 规范,用于解决回调金字塔问题。本文先介绍 Promises 相关规范,然后再通过解读一个迷你的 Promises 以加深理解。

什么是 Promise

一个 Promise 对象代表一个目前还不可用,但是在未来的某个时间点可以被解析的值。它允许你以一种同步的方式编写异步代码。例如,如果你想要使用 Promise API 异步调用一个远程的服务器,你需要创建一个代表数据将会在未来由 Web 服务返回的 Promise 对象。唯一的问题是目前数据还不可用。当请求完成并从服务器返回时数据将变为可用数据。在此期间,Promise 对象将扮演一个真实数据的代理角色。接下来,你可以在 Promise 对象上绑定一个回调函数,一旦真实数据变得可用这个回调函数将会被调用。

Promise 对象曾经以多种形式存在于许多语言中。

去除厄运的回调金字塔(Pyramid of Doom)

Javascript 中最常见的反模式做法是回调内部再嵌套回调。

 // 回调金字塔
asyncOperation(function(data){
// 处理 `data`
anotherAsync(function(data2){
// 处理 `data2`
yetAnotherAsync(function(){
// 完成
});
});
});

引入 Promises 之后的代码

 promiseSomething()
.then(function(data){
// 处理 `data`
return anotherAsync();
})
.then(function(data2){
// 处理 `data2`
return yetAnotherAsync();
})
.then(function(){
// 完成
});

Promises 将嵌套的 callback,改造成一系列的.then的连缀调用,去除了层层缩进的糟糕代码风格。Promises 不是一种解决具体问题的算法,而已一种更好的代码组织模式。接受新的组织模式同时,也逐渐以全新的视角来理解异步调用。

3、Fetch API

Fetch API 提供了一个获取资源的接口(包括跨域)。任何使用过 XMLHttpRequest 的人都能轻松上手,但新的API提供了更强大和灵活的功能集。

Fetch 提供了对 Request 和 Response (以及其他与网络请求有关的)对象的通用定义。使之今后可以被使用到更多地应用场景中:无论是service workers、Cache API、又或者是其他处理请求和响应的方式,甚至是任何一种需要你自己在程序中生成响应的方式。

它还提供了一种定义,将 CORS 和 HTTP 原生的头信息结合起来,取代了原来那种分离的定义。

4、闭包 (closure)

闭包和词法作用域非常相近。一个关于闭包如何工作的更好或者更实际的例子就是返回一个函数的引用。

我们可以返回域中的东西,使得它们可以被其父域所用。

当你在函数里声明一个变量时,你只能在函数内访问。这些变量的作用域就被限制在函数里了。

如果你在一个函数内又定义了内部函数,那么这个内部函数就被称作闭包。它仍可以访问外部函数的作用域。

二、

在开发过程中,我们向服务端发送请求,一般会使用三种方式, XMLHttpRequest(XHR),Fetch ,jQuery实现的AJAX。
其中, XMLHttpRequest(XHR)和Fetch是浏览器的原生API,jquery的ajax其实是封装了XHR。
这里我们主要比较一下Fetch与XHR在异步请求中的使用示例。

XMLHttpRequest

 var xhr;
if (window.XMLHttpRequest) {  // Mozilla, Safari...
 xhr = new XMLHttpRequest();
} else if (window.ActiveXObject) { // IE
 try {
 xhr = new ActiveXObject('Msxml2.XMLHTTP');
  } catch (e) {
  try {
  xhr = new ActiveXObject('Microsoft.XMLHTTP');
  } catch (e) {}
  }
}
if (xhr) {
 xhr.onreadystatechange = onReadyStateChange;
  xhr.open('POST', '/api', true);
  // 设置 Content-Type 为 application/x-www-form-urlencoded
  // 以表单的形式传递数据
 xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
  xhr.send('username=admin&password=root');
} // onreadystatechange 方法
function onReadyStateChange() {
  // 该函数会被调用四次
 console.log(xhr.readyState);
 if (xhr.readyState === 4) {
   // everything is good, the response is received
  if (xhr.status === 200) {
   console.log(xhr.responseText);
  } else {
   console.log('There was a problem with the request.');
   }
 } else {
  // still not ready
  console.log('still not ready...');
 }
}

从上边的代码可以看出,XMLHttpRequest 是一个非常粗糙的API,不符合关注分离的原则,配置和调用方式非常混乱,前端程序员们不仅要做各个浏览器的兼容性,还饱受回调地狱的折磨,这显然不是一个好的选择。

Fetch

 fetch(...).then(fun2)
.then(fun3) //各依赖有序执行
.....
.catch(fun)

从上边的代码可以看出,fetch解决了回调地狱问题,使用简便,虽然还是有Callback的影子,但是看起来舒服多了。

Fetch 优点:

  1. 语法简洁,更加语义化
  2. 基于标准 Promise 实现,支持 async/await
  3. 同构方便,使用isomorphic-fetch

Fetch和xhr的不同
          1、fetch虽然底层,但是还是缺少一些常用xhr有的方法,比如能够取消请求(abort)方法
          2、fetch在服务器返回4xx、5xx时是不会抛出错误的,这里需要手动通过,通过response中的ok字段和status字段来判断

---------------------
部分内容摘自网络:
https://www.jianshu.com/p/35123b048e5e
http://www.ruanyifeng.com/blog/2012/12/asynchronous%EF%BC%BFjavascript.html
https://developer.mozilla.org/zh-CN/docs/Web/API/Fetch_API/Using_Fetch

JavaScript 之 异步请求的更多相关文章

  1. [TimLinux] JavaScript 取消异步请求

    1. xhr.abort() 这个函数可以用来取消XMLHttpRequest()发起的异步请求,不是xhr.close()哦. 2. 场景 比如说,在关闭一个模态框后,数据可能还没有过来,这个时候需 ...

  2. JavaScript处理异步请求的几种方式(取异步函数返回值)

    JavaScript处理异步的几种方式 Javascript语言的执行环境是"单线程"(single thread,就是指一次只能完成一件任务.如果有多个任务,就必须排队,前面一个 ...

  3. 掌握 Ajax,第 2 部分: 使用 JavaScript 和 Ajax 发出异步请求

    转http://www.ibm.com/developerworks/cn/xml/wa-ajaxintro2/ 掌握 Ajax,第 2 部分: 使用 JavaScript 和 Ajax 发出异步请求 ...

  4. Javascript异步请求你能捕获到异常吗?

    Javascript异步请求你能捕获到异常吗? 异常处理是程序发布之前必须要解决的问题,不经过异常处理的应用会让用户对产品失去信心.在异常处理中,我们一贯的做法是按照函数调用的次序,将异常从数据访问层 ...

  5. 解决多次异步请求紊乱问题 - JavaScript

    加入目前的需求这样的:       左边的菜单链接,点击后通过异步请求返回其HTML代码,然后innerHTML到右面的DIV中,加入切换菜单的速度非常快,最终会导致请求紊乱. 可以加入消息管理机制, ...

  6. javascript 异步请求封装成同步请求

    此方法是异步请求封装成同步请求,加上token验证,环境试用微信小程序,可以修改文件中的ajax,进行封装自己的,比如用axios等 成功码采用标准的 200 到 300 和304 ,需要可以自行修改 ...

  7. javascript for循环+异步请求导致请求顺序不一致

    工作中遇到一个问题 for循环,再把循环出来的ID再进行二次请求 这就导致一个问题 请求结果返回顺序不一致 原因:异步请求会把回调事件放入微任务事件队列,宏任务执行完毕再执行微任务,具体参考事件队列机 ...

  8. ajax异步请求

    做前端开发的朋友对于ajax异步更新一定印象深刻,作为刚入坑的小白,今天就和大家一起聊聊关于ajax异步请求的那点事.既然是ajax就少不了jQuery的知识,推荐大家访问www.w3school.c ...

  9. AJAX实现简单的注册页面异步请求

    p { margin: 0px; padding: 0px } AJAX简介 (1)AJAX = 异步 JavaScript 和 XML. (2)AJAX 是一种用于创建快速动态网页的技术. (3)通 ...

随机推荐

  1. IDEA快速升级模块版本号

    使用场景 一个多模块的项目中,在功能用重大更新后,需要升级版本号,如果不使用工具,需要手动更改每个pom.xml文件,而使用工具,就可以非常快速的完成版本号的更改. 基本步骤 0.  idea执行ma ...

  2. c# quartz

    quartz调度核心元素: Scheduler:任务调度器,是实际执行任务调度的控制器.在spring中通过SchedulerFactoryBean封装起来. Trigger:触发器,用于定义任务调度 ...

  3. mybatis-plus 乐观锁

    参见:https://mp.baomidou.com/guide/optimistic-locker-plugin.html#%E4%B8%BB%E8%A6%81%E9%80%82%E7%94%A8% ...

  4. Golang的基础数据类型-整型

    Golang的基础数据类型-整型 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.整型概述 Go语言的整数类型一共有10个. int: 默认是有符号(signed)整形,占用空间 ...

  5. 2.10 学习总结 之 JQ加强

    一.说在前面  昨天 完成了体温统计APP的编写 今天 学习json数据结构 二.学习总结 1.json数据结构 1)什么是json: JSON(JavaScript Object Notation) ...

  6. UVA - 225 Golygons (黄金图形)(回溯)

    题意:平面有k个障碍点.从(0,0)出发,第一次走1个单位,……,第n次走n个单位,恰好回到(0,0),每次必须转弯90°,图形可以自交,但不能经过障碍点.按字典序输出所有移动序列,并输出序列总数. ...

  7. vCenter组件和服务

    1).随VMware Platform Services Controller一起安装的服务 a. vCenter Single Sign-On身份验证服务 b. vSphere 许可证服务 c. V ...

  8. 指令——ls

    Liunx基础命令 一.Liunx系统下的一般命令格式. 命令——实际上就是在Liunx终端中,在命令行中输入的内容. Liunx中一个命令的完整格式为: #指令主体(空格) [选项](空格) [操作 ...

  9. bzoj 2281: [Sdoi2011]黑白棋

    再次,,,,,虚(一开始看错题了,看成一次移动一个棋子,能移动1-d个格子...这样的话有没有大神会做??本蒟蒻就教) 额,,直接%%%%把...http://hzwer.com/5760.html ...

  10. C#的listview

    listView1.Items.Clear(); ListViewItem listitem = new ListViewItem(字符串);//这是第一列的内容,需要,而且必须通过构造方法添加 ; ...