经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » JS/JS库/框架 » JavaScript » 查看文章
JavaScript异步编程2——结合XMLHttpRequest使用Promise
来源:cnblogs  作者:charlee44  时间:2021/4/19 8:55:53  对本文有异议

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页面:

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="utf-8">
  5. <script src="./3rdParty/jquery-3.5.1.js"></script>
  6. <title>样例</title>
  7. </head>
  8. <body>
  9. <div id = "container"> </div>
  10. <script src="./PromiseTest.js"></script>
  11. </body>
  12. </html>

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

  1. $(function () {
  2. var url = "./1.json";
  3. var req = new XMLHttpRequest();
  4. req.open('GET', url);
  5. req.onload = function () {
  6. if (req.status == 200) {
  7. console.log(req.response);
  8. } else {
  9. throw new Error(req.statusText);
  10. }
  11. };
  12. req.onerror = function () {
  13. throw new Error("Network Error");
  14. };
  15. req.send();
  16. });

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

  1. function get(url) {
  2. return new Promise(function (resolve, reject) {
  3. var req = new XMLHttpRequest();
  4. req.open('GET', url);
  5. req.onload = function () {
  6. //即使是404也会进入这个相应函数,所以需要检测状态
  7. if (req.status == 200) {
  8. //完成许诺,返回响应文本
  9. resolve(req.response);
  10. } else {
  11. //完成未完成,返回错误
  12. reject(Error(req.statusText));
  13. }
  14. };
  15. // 发生错误时的相应函数
  16. req.onerror = function () {
  17. reject(Error("Network Error"));
  18. };
  19. // 发送请求
  20. req.send();
  21. });
  22. }
  23. var addressUri = "./1.json";
  24. get(addressUri).then(function (response) {
  25. console.log("Success!", response);
  26. }, function (error) {
  27. console.error("Failed!", error);
  28. });

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

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

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

3. 参考

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

原文链接:http://www.cnblogs.com/charlee44/p/14670458.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号