JavaScript异步编程之Promise的初步使用详解

作者:charlee44 时间:2024-04-30 08:53:58 

1. 概述

Promise对象是ES6提出的的异步编程的规范。说到异步编程,就不得不说说同步和异步这两个概念。

从字面意思理解同步编程的话,似乎指的是两个任务同步运行,如果这样理解就错了(至少笔者再没有接触到这个概念的时候有这种误解)。同步和异步指的是代码指定执行的顺序(结构化编程范式的执行顺序总是由上至下,由前往后的),如果执行的顺序与代码的相同,就是同步;如果不同,就是异步。

最初,操作系统都是基于命令行的,所有的的语言设计出来也天然是同步的语句,在这种情况下,也不需要异步编程。但是很快,图形操作界面就出来了,所有的程序设计语言都不得不跟GUI打交道了。我们必须了解的是,GUI程序是一个不停绘制的界面程序:


while(done)
{
   dosomething();
   drawGUI();
}

如果每个循环中执行的任务dosomething()的事件太长,就会导致界面迟迟得不到绘制命令,直观的表现就是卡顿。为了解决这个问题,使用JavaScript作为脚本的浏览器一般都会采用事件循环(Event Loop)的机制:

  • 将耗时的行为规定为事件,事件与响应回调函数绑定。

  • 每个循环,优先处理同步代码。

  • 同步代码完成,按照先后顺序遍历事件。

  • 在剩下的没有同步代码的循环中,依次执行事件的相应函数。

这样,在单线程的情况下,就修改了任务的执行顺序,实现了异步的机制。因为同步的行为总是很快完成及时进行了界面绘制,界面卡顿的现象也大为改善了。

事件循环机制将UI设备的输入输出规定为事件,实际上,耗时的行为非常多,但是一般都与IO相关,与IO相关的行为,JavaScript都提供了异步行为的代码。例如,这里要用的一个加载图片的实例。

2. 详论

首先准备一个HTML页面PromiseTest.html,在这个HTML页面中加载JS的脚本PromiseTest.js:


<!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>

原生的JS的图像对象Image,是通过事件的形式来实现图像的异步加载的:


$(function () {    
   var img = new Image();
   img.onload = function () {
       $(img).appendTo($('#container'));        
   };
   img.src = "./img.jpg";    
});

为Image的事件句柄onload,添加一个相应函数,当图像装载完成之后,就将装载好的Image添加到HTML页面的某个div元素子节点下。通过浏览器打开这个页面,会直接显示对应地址的图片。

这个JS脚本当然也可以通过Promise来改写:


$(function () {    
   function getImg(uri){
       return new Promise(function(resolve, reject){
           var img = new Image();
           img.onload = function () {
               resolve(img);
           };
           img.onerror = function () {
               reject(Error("Load Image Error!"));
           }
           img.src = uri;
       });  
   }  

var imgUri = "./img.jpg";
   getImg(imgUri).then(function(img){
       $(img).appendTo($('#container'));
   }, function(error){
       console.error("Failed!", error);
   })
});

粗看起来,使用Promise,似乎使得程序显得更加复杂和繁复了。但是我们要深入理解Promise机制的内涵,这样设计并不是为了好玩。

  • Promise对象代表的是一个预定要做、但是还未开始做的行为。既然是一个行为,当然得进行计划,并对行为结果做出规定:如果成功了,就执行resolve;如果失败了,就执行reject。一般我们可以定义一个function,并且返回一个Promise对象。

  • 调用返回Promise对象的function,这样这个想要进行的行为就真正启动了。不过resolve和reject只是两个回调函数,那么就通过then方法来规定成功和失败对应的真正的处理函数。

可以看到,这样的设计看起来很繁复,但是却很像是一个同步行为:规定一个未完成行为对象,行为完成了如何处理,行为失败了又如何处理。而这也是Promise的目的:使得异步操作更像是一个同步的行为。

3. 参考

同步(Synchronous)和异步(Asynchronous)

简述JS单线程异步实现原理

JavaScript 运行机制详解:再谈Event Loop

来源:https://www.cnblogs.com/charlee44/archive/2021/04/11/14644509.html

标签:js,Promise,使用
0
投稿

猜你喜欢

  • BootStrap学习笔记之nav导航栏和面包屑导航

    2023-08-16 12:33:22
  • 图书管理系统的sqlserver数据库设计示例

    2024-01-18 08:50:50
  • Oracle修改表空间大小的方法

    2024-01-13 04:14:49
  • Python中的集合一起来学习一下

    2022-05-01 05:06:59
  • 用python修改excel表某一列内容的操作方法

    2022-01-22 20:51:29
  • SQL Server中的XML数据进行insert、update、delete

    2024-01-28 08:59:50
  • Python ArcPy批量掩膜、重采样大量遥感影像的操作

    2023-12-23 14:48:55
  • Python 面向对象之类class和对象基本用法示例

    2023-01-02 20:15:01
  • Python中几种导入模块的方式总结

    2021-09-20 08:17:14
  • 踩坑:pytorch中eval模式下结果远差于train模式介绍

    2021-10-06 22:27:49
  • Python3.5实现的三级菜单功能示例

    2023-08-01 13:37:26
  • python中os包的用法

    2021-07-11 07:24:02
  • 最新Pygame zero最全集合

    2022-07-18 13:14:16
  • 教你用Python读取CSV文件的5种方式

    2022-12-11 15:32:51
  • Python3中的2to3转换工具使用示例

    2022-04-26 17:33:36
  • Python2和Python3中@abstractmethod使用方法

    2021-12-29 08:55:36
  • 浅谈JavaScript编程语言的编码规范

    2010-08-18 12:08:00
  • python制作抽奖程序代码详解

    2022-05-04 08:51:18
  • 使用TensorFlow直接获取处理MNIST数据方式

    2022-12-16 22:35:49
  • 如何利用Pandas删除某列指定值所在的行

    2023-10-29 11:49:39
  • asp之家 网络编程 m.aspxhome.com