Promise浅析(一)——基础篇
发布日期:2021-05-07 10:15:39 浏览次数:25 分类:精选文章

本文共 3965 字,大约阅读时间需要 13 分钟。

之前在慕课网上学习nodejs时接触到了promise这个东东,感觉还不错,于是就想系统的学习一下。但很快就发现网上关于promise的资料有点少,于是就萌生了写有关promise的系列博客的想法。由于这个系列的博客我也是边学边写,难免会出现纰漏,所以有误的地方还请大家多多指正。

基础篇主要介绍什么是promise、promise的基本API。下面就进入正题。

一、与Promise相关的概念

1.什么是Promise/Promise有什么用
首先来看定义——Promise是js针对异步场景的解决方案,它可以以同步的方式编写代码,执行的操作却是异步的。
举个栗子,假如我们要实现一个动画——有三个小球,分别为红色、黄色、绿色,最后展示的效果是绿球先移动一段距离,结束移动后黄球移动,黄球移动结束后红球移动,红球移动一段距离后再移回原位,红球归位后黄球移动归位,黄球移动归位后绿球移动归位,在黄球归位以后动画结束。
不知道在看完整个动画的流程以后,大家对该动画的实现有什么想法,下面分享一下我的代码。首先是html部分

    
promise animation

这里大家需要在下方引入bluebird库的部分。目前的实例还不需要用到promise库。但由于Promise是ES6中引入的概念,为了防止某些运行环境不支持promise,我们采用bluebird库进行实现。之后的例子会详细介绍如何获得及使用bluebird库。

那么,首先如何获取bluebird库呢?我是用npm来获取的。在node.js运行环境中,输入npm install bluebird -g来获取bluebird库,运行完成之后的bluebird库目录结构如下所示
这里写图片描述
进入到js文件夹,我们会看到
这里写图片描述
有browser与release两个文件夹,browser文件夹中放置的是在浏览器端使用的bluebird库,就类似于jQuery,打开该文件夹,我们可以看到
这里写图片描述
接下来就可以把想要使用的库文件拷贝到相应位置进行引用。
下面来看一下css代码

*{   margin:0;padding:0;}.ball{    position:absolute;    width:40px;    height:40px;    border-radius:20px;}#balla{    background-color: red;}#ballb{    background-color: yellow;}#ballc{    background-color: green;}

最后显示在浏览器的样子就是这样子的

这里写图片描述
那么,如果用原始的回调的方式进行编写,代码就应该想这样子

var balla=document.querySelector("#balla");var ballb=document.querySelector("#ballb");var ballc=document.querySelector("#ballc");//ball传入小球的id,distance为移动的距离function animateBall(ball,distance,callback){       setTimeout(function(){           //获取当前小球的位置        var position=parseInt(ball.style.left,10);        if(position==distance){            callback();        }else if(position
distance){ position--; ball.style.left=position+"px"; animateBall(ball,distance,callback); } },13); //13毫秒每帧}animateBall(ballc,500,function(){ animateBall(ballb,450,function(){ animateBall(balla,400,function(){ animateBall(balla,0,function(){ animateBall(ballb,50,function(){ animateBall(ballc,100,function(){ }); }); }); }); });});

我们可以看到,在最后的回调部分,噼里啪啦的写了好几行,目前的需求写起来还算比较简单,但如果回调相当之多肿么办?这样子嵌套着写也不方便日后的维护,而且回调函数真正的问题在于它剥夺了我们使用 return 和 throw 这些关键字的能力,顺便也剥夺了我们使用链式编程的权力。于是乎,js便引入了promise来解决这个问题。

2.Promise构造函数

<1>promise构造函数接受一个函数作为参数,该函数包含两个参数,分别是resolve方法与reject方法

var promise=window.Promise;//获取全局promise对象function promiseAnimate(ball,distance){       return new promise(function(resolve,reject){           function _animateBall(){               setTimeout(function(){                   var position=parseInt(ball.style.left,10);                if(distance<0){                    reject(new Error("距离不能为负数"));                }else if(position==distance){                    resolve("完成移动");                }else if(position
distance){ position--; ball.style.left=position+"px"; _animateBall(); } },13); }; _animateBall(); });}

在分析代码之前,我们需要了解promise的特点

<2>promise的特点
promise对象有三种状态,分别为“未完成”(pending)、“已完成”(fullilled或者叫做resolved)、“失败”(rejected)。
只有异步操作的结果可以决定当前是哪一种状态。
一旦状态改变,就不会再变,任何时候都可以得到这个结果,并且状态只可能从pending变为resolved,或者从pending变为rejected
<3>构造函数分析
如果异步操作成功,则用resolve方法把promise对象的状态从pending转为resolved;如果失败,则从pending转为rejected。

下面是用最简单的promise进行编写。由于本节只简单介绍一下promise,所以还没有展示如何获取并处理错误。这些将在下一篇博客中为大家详细讲解。

promiseAnimate(ballc,500).then(function(){    return promiseAnimate(ballb,450)}).then(function(){    return promiseAnimate(balla,400)}).then(function(){    return promiseAnimate(balla,0)}).then(function(){    return promiseAnimate(ballb,50)}).then(function(){    return promiseAnimate(ballc,100)}).then(function(value){    console.log(value)    /*前面的每个.then方法中函数的参数都可以是value,并且也可以console出来“完成移动”*/});

二、基本API

promise对象的基本API有:
promise.resolve()、promise.reject()、promise.prototype.then()、promise.prototype.catch()、promise.all()

到此为止,我们的promise浅析的第一部分就结束了,下一章将讲解promise基本API的使用。敬请期待。最后为大家分享一下promise系列博客主要参考的网站

上一篇:MongoDB地理位置索引
下一篇:“单线程/多线程”与“同步/异步”还有“阻塞/非阻塞”

发表评论

最新留言

留言是一种美德,欢迎回访!
[***.207.175.100]2025年04月09日 22时10分39秒