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

 更新时间:2021年04月14日 08:42:46   作者:charlee44  
这篇文章主要介绍了JavaScript异步编程之Promise的初步使用,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

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

到此这篇关于JavaScript异步编程之Promise的初步使用的文章就介绍到这了,更多相关js Promise使用内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Javascript 函数中的参数使用分析

    Javascript 函数中的参数使用分析

    关于JS中的函数,相信大家已经很了解了,其中有些特性呢,感觉还是值得提一提的,下面就说说JS中的函数吧。
    2010-03-03
  • javascript DOM实用学习资料

    javascript DOM实用学习资料

    比较详细的实例分析了dom的一些常用方法
    2008-09-09
  • javascript中的event loop事件循环详解

    javascript中的event loop事件循环详解

    这篇文章主要给大家介绍了关于javascript中event loop事件循环的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2018-12-12
  • JavaScript按值删除数组元素的方法

    JavaScript按值删除数组元素的方法

    这篇文章主要介绍了JavaScript按值删除数组元素的方法,涉及javascript操作数组的相关技巧,非常具有实用价值,需要的朋友可以参考下
    2015-04-04
  • 实现图片预加载的三大方法及优缺点分析

    实现图片预加载的三大方法及优缺点分析

    本文介绍了实现图片预加载的三大方法(CSS/JAVASCRIPT/AJAX)以及这三种方法的优缺点分析,是篇非常值得推荐的文章,小伙伴们可要仔细研究下。
    2014-11-11
  • JS中用try catch对代码运行的性能影响分析

    JS中用try catch对代码运行的性能影响分析

    要捕获JavaScript代码中的异常一般会采用 try catch,不过try catch的使用是否是对代码性能产生影响呢?答案是肯定有的,但是有多少不得而知。下面这篇文章就给大家详细介绍了在JS中用try catch对代码运行的性能影响,有需要的朋友们可以参考借鉴。
    2016-12-12
  • layui使用label标签的方法

    layui使用label标签的方法

    今天小编就为大家分享一篇layui使用label标签的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-09-09
  • BootStrap框架中的data-[ ]自定义属性理解(推荐)

    BootStrap框架中的data-[ ]自定义属性理解(推荐)

    这篇文章主要介绍了BootStrap框架中的data-[ ]自定义属性理解(推荐),非常不错,具有参考借鉴价值,需要的朋友可以参考下
    2017-02-02
  • JavaScript的null和undefined区别示例介绍

    JavaScript的null和undefined区别示例介绍

    在Javascript中对于这种生命后没有给定初始值的变量,就给他一个undefined,如果要将一个标识符声明称object类型,但是暂时不给他实例,那么就可以将它先初始化为null
    2014-09-09
  • 通过javascript获取iframe里的值示例代码

    通过javascript获取iframe里的值示例代码

    iframe里的值在实现一些比较特殊功能时需要获取的,下面为大家详细介绍下使用javascript获取iframe里值的方法,感兴趣的各位可以参考下哈
    2013-06-06

最新评论