1. 概述

在上一篇文章《JavaScript异步编程1——Promise的初步使用》,简单介绍了一下Promise的初步使用。复习一下,Promise异步编程可以用如下的范式来编写:

  1. 定义一个函数(function A),这个函数返回一个Promise对象。
  2. Promise对象的参数也是一个function B,内部进行了一个异步操作(通常是JavaScript提供的API)。
  3. function B对象的参数是两个回调函数resolve和reject。如果函数内部进行的异步操作成功,回调resolve;否则回调reject。
  4. 调用function A,返回一个Promise对象,这样异步操作就启动了。
  5. 调用Promise对象的then方法,参数是resolve和reject的真正响应函数。当异步操作完成了,就会执行相应分支的响应函数。

采用以上范式,可以通过Promise来进行Ajax操作,也就是XMLHttpRequest,毕竟这个操作在Web应用中实在太常见了。

2. 详论

首先仍然是准备一个HTML页面:

<!DOCTYPE html>
<html> <head>
<meta charset="utf-8">
<script src="./3rdParty/jquery-3.5.1.js"></script>
<title>样例</title>
</head> <body>
<div id = "container"> </div>
<script src="./PromiseTest.js"></script>
</body> </html>

如果不使用Promise,那么相应的JavaScript代码为:

$(function () {

    var url = "./1.json";

    var req = new XMLHttpRequest();
req.open('GET', url); req.onload = function () {
if (req.status == 200) {
console.log(req.response);
} else {
throw new Error(req.statusText);
}
}; req.onerror = function () {
throw new Error("Network Error");
}; req.send();
});

可以看到这里仍然是通过事件机制来实现异步行为。接下来采用前面提到的编程范式将其改造成Promise机制:

function get(url) {
return new Promise(function (resolve, reject) {
var req = new XMLHttpRequest();
req.open('GET', url); req.onload = function () {
//即使是404也会进入这个相应函数,所以需要检测状态
if (req.status == 200) {
//完成许诺,返回响应文本
resolve(req.response);
} else {
//完成未完成,返回错误
reject(Error(req.statusText));
}
}; // 发生错误时的相应函数
req.onerror = function () {
reject(Error("Network Error"));
}; // 发送请求
req.send();
});
} var addressUri = "./1.json";
get(addressUri).then(function (response) {
console.log("Success!", response);
}, function (error) {
console.error("Failed!", error);
});

改造成Promise的过程与上一章并没有什么不同,只不过函数内部调用XMLHttpRequest的流程更加复杂些。这两个例子都是将事件改造成Promise,那不是意味着对于异步编程而言,Promise要优于事件呢?

不能完全这么肯定,但是可以确定的是事件并不总是异步编程的最优实践。一个很显然的问题就是:事件很适合处理在同一对象上多次发生的事情,但是事件侦听器的响应函数可能并不是我们想要的——更多情况下,我们只想要直到两个状态,当异步操作完成的时候该做什么,当异步操作失败的时候又该做什么,而这正是Promise擅长处理的。

例如这里的XMLHttpRequest操作,事件响应函数onload中的所有行为,并不都是异步请求成功时需要完成的,只有检测访问请求状态为200时候,才需要进行请求成功时的回调函数。使用Promise,可以更准确的进行异步行为。

3. 参考

  1. Ajax原理-原生js的XMLHttpRequest对象意义
  2. Javascript异步编程的4种方法

JavaScript异步编程2——结合XMLHttpRequest使用Promise的更多相关文章

  1. JavaScript 异步编程(二):Promise

    PromiseState Promise 有一个 [[PromiseState]] 属性,表示当前的状态,状态有 pending 和 fulfill 以及 reject. 从第一个 Promise 开 ...

  2. javascript异步编程,promise概念

    javascript 异步编程 概述 采用单线程模式工作的原因: 避免多线dom操作同步问题,javascript的执行环境中负责执行代码的线程只有一个 内容概要 同步模式和异步模式 事件循环和消息队 ...

  3. JavaScript异步编程原理

    众所周知,JavaScript 的执行环境是单线程的,所谓的单线程就是一次只能完成一个任务,其任务的调度方式就是排队,这就和火车站洗手间门口的等待一样,前面的那个人没有搞定,你就只能站在后面排队等着. ...

  4. JavaScript异步编程的主要解决方案—对不起,我和你不在同一个频率上

    众所周知(这也忒夸张了吧?),Javascript通过事件驱动机制,在单线程模型下,以异步的形式来实现非阻塞的IO操作.这种模式使得JavaScript在处理事务时非常高效,但这带来了很多问题,比如异 ...

  5. javascript异步编程的前世今生,从onclick到await/async

    javascript与异步编程 为了避免资源管理等复杂性的问题, javascript被设计为单线程的语言,即使有了html5 worker,也不能直接访问dom. javascript 设计之初是为 ...

  6. JavaScript异步编程(2)- 先驱者:jsDeferred

    JavaScript当前有众多实现异步编程的方式,最为耀眼的就是ECMAScript 6规范中的Promise对象,它来自于CommonJS小组的努力:Promise/A+规范. 研究javascri ...

  7. Promises与Javascript异步编程

    Promises与Javascript异步编程 转载:http://www.zawaliang.com/2013/08/399.html 在如今都追求用户体验的时代,Ajax应用真的是无所不在.加上这 ...

  8. 5分种让你了解javascript异步编程的前世今生,从onclick到await/async

      javascript与异步编程 为了避免资源管理等复杂性的问题,javascript被设计为单线程的语言,即使有了html5 worker,也不能直接访问dom. javascript 设计之初是 ...

  9. 转: Promises与Javascript异步编程

    在如今都追求用户体验的时代,Ajax应用真的是无所不在.加上这些年浏览器技术.HTML5以及CSS3等的发展,越来越多的富Web应用出现:在给与我们良好体验的同时,Web开发人员在背后需要处理越来越多 ...

  10. JavaScript异步编程

    前言 如果你有志于成为一个优秀的前端工程师,或是想要深入学习JavaScript,异步编程是必不可少的一个知识点,这也是区分初级,中级或高级前端的依据之一.如果你对异步编程没有太清晰的概念,那么我建议 ...

随机推荐

  1. crontab guru

    https://crontab.guru/every-5-minutes Cron Job Monitoring crontab guru The quick and simple editor fo ...

  2. P4899 [IOI2018] werewolf 狼人 题解

    P4899 [IOI2018] werewolf 狼人 题解 题目描述 省流: \(n\) 个点,\(m\) 条边,\(q\) 次询问,对于每一次询问,给定一个起点 \(S\) 和终点 \(T\) , ...

  3. 手撕Vue-实现事件相关指令

    经过上一篇文章的学习,实现了界面驱动数据更新,接下来实现一下其它相关的指令,比如事件相关的指令,v-on 这个指令的使用频率还是很高的,所以我们先来实现这个指令. v-on 的作用是什么,是不是可以给 ...

  4. Hall定理(霍尔定理)证明及推广

    引言 网络上有许多Hall定理的证明,但是对于Hall定理的几个推广的介绍却少之又少,因此本文来简单介绍一下 注:为了使这篇文章看起来简单易懂,本文将不会使用图论语言,会图论的朋友们可以自行翻译为图论 ...

  5. [数据分析与可视化] 基于Python绘制简单动图

    动画是一种高效的可视化工具,能够提升用户的吸引力和视觉体验,有助于以富有意义的方式呈现数据可视化.本文的主要介绍在Python中两种简单制作动图的方法.其中一种方法是使用matplotlib的Anim ...

  6. Java内部类与匿名类

    内部类 定义: 一个类的内部又完整的嵌套了另一个类结构,被嵌套的类就被我们称为内部类,嵌套内部类的类被我们称为外部类 //外部类 class Outer { //内部类 class Inner { } ...

  7. 猜单词游戏(c++)

    #include<iostream> #include<string> #include<fstream> #include<cstdlib> #inc ...

  8. [Python急救站课程]蟒蛇的绘制

    Python的英文是有蟒蛇的意思,用Python画一条蟒蛇试试吧 一.普通蟒蛇的绘制 import turtle # 调用turtle(海龟绘图)加as t表示将库名改命名为t,后续用t.(函数名表式 ...

  9. 接口开放太麻烦?试试阿里云API网关吧

    前言 我在多方合作时,系统间的交互是怎么做的?这篇文章中写过一些多方合作时接口的调用规则和例子,然而,接口开放所涉及的安全.权限.监控.流量控制等问题,可不是简简单单就可以解决的,这一般需要专业的开放 ...

  10. 一篇文章带你了解Python基础测试工具——UnitTest

    一篇文章带你了解Python基础测试工具--UnitTest 测试人员一般使用Python作为主语言脚本来进行自动化开发,而Python自带的UnitTest脚本通常就是测试人员首先掌握的 那么本篇文 ...