今天在进入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. Redis的集群模式

    集群 即使使用哨兵,此时的Redis集群的每个数据库依然存有集群中的所有数据,从而导致集群的总数据存储量受限于可用存储内存最小的数据库节点,形成木桶效应.由于Redis中的所有数据都是基于内存存储,这 ...

  2. AS导入项目报错:Plugin with id 'com.android.application' not found.

    从github或第三方Demo中获取的项目导入到AndroidStudio中报错Plugin with id 'com.android.application' not found.:今天导入一个讯飞 ...

  3. .NET/C#发起GET和POST请求的几种方法

    using System.Net; GET:   1 2 3 var request = (HttpWebRequest)WebRequest.Create("http://www.lead ...

  4. element-ui 带单选框的表格

    效果:不只是带单选框,点击当前行单选框选中状态网上查了一些发现很多都是只能点击当前radio选中当前行,配合element-ui的单选table时发现两个的选择状态是不一致的,所以调整了一下效果 提供 ...

  5. [java,2018-01-16] HttpClient发送、接收 json 请求

    最近需要用到许多在后台发送http请求的功能,可能需要发送json和xml类型的数据. 就抽取出来写了一个帮助类: 首先判断发送的数据类型是json还是xml: import org.dom4j.Do ...

  6. Structs 2 session 学习

    后台获取 值类型  request.getSession().setAttribute("username", user.getUserName());  对象类型   reque ...

  7. File Input Features

    文件输入功能 1.该插件将将一个简单的 HTML 文件输入转换为高级文件选取器控件.将有助于对不支持 JQuery 或 Javascript 的浏览器的正常 HTML 文件输入进行回退. 2.文件输入 ...

  8. Oracle 日志归档 自动清理

    exp emis/emis@orcl file=d:\backup\oracle\oracle%date:~0,10%.dmp owner=emis log=d:\backup\oracle\orac ...

  9. uva-10340-水题

    题意:字符串匹配,看样例输入理解题意 直接循环 #include <string> #include<iostream> #include<map> #includ ...

  10. NAS 百科 —— http://baike.baidu.com/item/NAS%E7%BD%91%E7%BB%9C%E5%AD%98%E5%82%A8

    NAS(Network Attached Storage)网络存储基于标准网络协议实现数据传输,为网络中的Windows / Linux / Mac OS 等各种不同操作系统的计算机提供文件共享和数据 ...