今天在进入Promise代码之前,我们先来用个例子来解释Promise是什么。

未来值

假设我们今天来到快餐店,点了一个汉堡,付钱给店员。

点了餐点并付费,可以理解为我们发送了一个请求,希望得到一个回传值(也就是汉堡)。

不过常见情况是,汉堡还没做好,不能立即给我,店员给了我一张收据上面写着点餐号码。这个点餐号码是一种「我欠你」的承诺(promise),确保我最后能够拿到我的汉堡。

所以只要拿着收据,我就能确保我未来的汉堡,不需要去担心。这样在等待的同时我就能够做其他事情,像是滑手机。

直到店员喊了我的号码,我拿着我的收据到柜台给店员换得了我的汉堡。

换句话说,一旦未来值准备就绪,我就能够用手上对值的承诺(value-promise)交换那个值本身。

但还有另一种结果,就是叫了我的号码,我走过去后店员跟我说汉堡卖完了。

这时候我们可以看到未来值一个重要的特性:代表成功,也可能代表失败。

也就是说Promise物件的设计就是针对异步函式的执行结果所设计的,最后的结果要不然就用一个回传值来fulfilled(实现),要不然就用一个理由(错误)来rejected(拒绝)。

那到底要怎么用呢?首先我们要先建立一个Promise物件:

var promise = new Promise(function(resolve,reject){

//成功时

resolve(value)

//失败时

reject(reason)

});

promise.then(function(value){

// on fulfillment(已实现时)

},function(reason){

// on rejection(已拒绝时)

})

建构式传入参数需要一个函式,称为executor有强烈执行的意味,当传入这个函式时,会在建构式回传物件实体前立即执行,也就是说Promise会立即决定里面的状态,resolve或reject,两者都必须是函式类型。

成功执行resolve(value)而Promise物件的状态会跑到fulfilled状态固定住(cumminsathletic);

失败或是发生错误时执行reject(reason)而Promise物件的状态会跑到rejected状态固定住。

也因为与一般物件实体化过程不太一样,所以通常会先包在一个函式中,需要使用时再呼叫函式来产生Promise物件:

function generatePromise(value){

return new Promise(function(resolve,reject){

if(value)

resolve(value)//已实现,成功

else

reject(reason)//有错误,已拒绝,失败

});

}

再来刚刚上面示例有看到说promise后面接着then。那then是什么呢?

then

then在Promise标准中是一个重要的方法,代表「然后、接着或接下来」的意思。then方法物件被称为thenable物件,我们来看个示例:

promise.then(onFulfilled,onRejected);

promise.then(function(value){

// fulfillment

},function(reason){

// rejection

});

then一样用两个函式当作参数传入,onFulfilled和onRejected。onFulfilled是当Promise物件状态转为fulfilled时呼叫的函式,会有一个传入参数值value可用;onRejected则是Promise物件状态转为rejected时呼叫,会有一个传入参数值reason可用。

而在最后,then会回传另一个「新的Promise物件」。

讲了那么多概念上的东西是不是令人难以理解?没关系,这边用个实际示例来讲解:

var promise = new Promise(function(resolve,reject){

resolve(1)

})

promise

.then(function(value){

console.log(value)// 1

return value + 1

})

.then(function(value){

console.log(value)// 2

})

then方法中的onFulfilled函式,也就是第一个传入的函式参数,它是有值时使用的函式,经过连锁的结构,如果要把值往下传递,可以用回传值的方式,让这个值可以继续的往下面的then方法传送。

那如果不用Promise,直接用callback会怎么样呢?

function doA(doB){

doB(1,doC)

}

function doB(val,doC){

doC(val+1)

}

function doC(val){

console.log(val);

}

doA(doB);

是不是看起来有点痛苦,而且我们还没加上如果失败时的函式呢(bargaintravel4u)!

今天就先到这边,如果有错误欢迎留言指正,明天会说明Promise失败时的函式用法!

学JS的心路历程-Promise(一)的更多相关文章

  1. 学JS的心路历程-Promise(三)

    今天我们来说then一些特殊情况以及Promise.all()与Promise.race(). 我们都知道函式作为参数传入时,可以参照的方式传入,也能传入时执行拿回传值作使用: function us ...

  2. 学JS的心路历程-Promise(二)

    昨天有说到Promise的创建以及then的用法,今天我们来看错误处理. then onRejected 我们昨天有提到说,then两个函式参数,onFulfilled和onRejected,而onR ...

  3. 学JS的心路历程Day26 - PixiJS -入坑

    后来知道也可以透过canvas让网页动起来! 而PixiJS是使用WebGL在canvas上绘制内容与制作动态 且同时有下列特色: 支持多点触控 掩码与混合模式 可外加WebGL滤镜 多装置支持 等等 ...

  4. 学JS的心路历程 -非同步执行

    JS是单线程的语言,也就是说同一时间只会执行一行程序,所以如果一段程序执行过久就会造成阻塞(blocking)的现象,必须等到它结束后才能执行下一段程序. 举个例子来说,如果我们今天要买便当,但是老板 ...

  5. 学JS的心路历程 -函式(三)this

    this是什么,取决于被呼叫的呼叫地点. 昨天有提到说,呼叫函式时候会传递隐含参数:arguments和this并讲解了arguments,今天我们就来探讨this吧! 什么是this 我们都会呼叫函 ...

  6. 学JS的心路历程 - JS应用

    各家电商网站都推出了各种活动和现今优惠券,当时在逛PTT时看到了有篇文章,提供代码教大家用JS的方式抢票,看了一下后发现好像很多人好奇这是怎么做的,于是就想说想一篇文章来讲解一下. 我们先来看一下折价 ...

  7. 学JS的心路历程 - JS的Class

    没错,你没有看错,虽然前面说JS是原型继承,但在ES6以后新增了class关键字!!! 不过底层实作仍然是以原型继承方式进行,所以基本上算是一个语法糖. 今天我们就来看一下如何使用吧! class 首 ...

  8. 学JS的心路历程-物件与原型(三)

    昨天有说明到函式与建构式的原型,及指定建构式函式原型为另一个建构式函式,但其实这会造成复写constructor的问题. 复写constructor的问题(vmwork) 我们昨天有提到「建构式函式可 ...

  9. 学JS的心路历程 -物件与原型(二)

    昨天有提到说Object.setPrototypeOf可以指定一个物件为另一个物件的原型,但有想过到底这个原型,也就是[[Prototype]]最终会到何处吗? 答案是Object.prototype ...

随机推荐

  1. 学习js第二天小结

    if-else if       ---------适用于区间范围的判断 If(判断条件--一般是boolean类型的值或是关系表达式或是逻辑表达式 ){ 要执行的代码; }else if(判断条件) ...

  2. Java - 26 Java 数据结构

    Java 数据结构 Java工具包提供了强大的数据结构.在Java中的数据结构主要包括以下几种接口和类: 枚举(Enumeration) 位集合(BitSet) 向量(Vector) 栈(Stack) ...

  3. Java 12 - Java StringBuffer和StringBuilder类

    Java StringBuffer和StringBuilder类 当对字符串进行修改的时候,需要使用StringBuffer和StringBuilder类. 和String类不同的是,StringBu ...

  4. useful tools and website

    1.https://www.processon.com/   在线流程图制作网站 2.http://www.easyicon.net/  专门下载图标的网站 3.https://www.lfd.uci ...

  5. Android图片变形,ImageView属性的设置。

    <ImageView android:id="@+id/iv" android:layout_width="match_parent" android:l ...

  6. centos7 图形化界面

    当你安装centos服务器版本的时候,系统默认是不会安装 CentOS 的图形界面程序的,比如:gnome或者kde, 那么如果你想在图形界面下工作的话,可以手动来安装CentOS Gnome GUI ...

  7. 解决从客户端(Content="<div><p ><p>12312...")中检测到有潜在危险的Request.Form 值。

    [HttpPost] [ValidateInput(false)]//解决从客户端(Content="<div><p ><p>12312..." ...

  8. 剑指Offer(四):重建二叉树

    说明: 1.本系列是根据<剑指Offer>这个系列做的一个小笔记. 2.直接动力是因为师兄师姐找工作很难,而且机械出生的我面试算法更难. 3.刚开始准备刷LeetCode.LintCode ...

  9. [UGUI]图文混排(七):动态表情

    帧动画脚本: http://www.cnblogs.com/lyh916/p/9194823.html 这里的动态表情,我使用的是固定间隔去刷新Image上的Sprite来实现的,即帧动画.这里可以将 ...

  10. 【Python爬虫实战】 使用代理服务器

    代理服务器:是一个处于我们与互联网中间的服务器,如果使用代理服务器,我们浏览信息的时候,先向代理服务器发出请求,然后又代理服务向互联网获取信息,再返回给我们使用代理服务器进行信息爬取,可以很好的解决I ...