Promise的用法讲解

Promise是一个构造函数,其自身有resolve reject all 等方法,原型上有then catch 等方法。

本文会着重讲解以下内容:

1、resolve和reject的用法。

2、all的用法。

3、重点讲解then的使用。

本教程所用引擎版本:5.2.13

本教程源码链接:
       https://github.com/shenysun/PromiseCourse

本教程参考:

【ES6 Promise 用法讲解】

http://www.cnblogs.com/whybxy/p/7645578.html

1、最简单的Promise

let any_1 = new Promise((resolve, reject)=> {

setTimeout(()=> {

console.log("经过1s,开始执行");

resolve("Promise执行完毕")

}, 1000);

})

/**

* Creates a new Promise.

* @param executor A callback used to initialize the promise. This callback is passed two arguments:

* a resolve callback used resolve the promise with a value or the result of another promise,

* and a reject callback used to reject the promise with a provided reason or error.

*/

new(executor: (resolve: (value?: T | PromiseLike) => void, reject: (reason?: any) => void) => void): Promise;

Promise的构造函数接收一个函数的参数,此函数有两个参数:resolve , reject,分别表示一步操作执行成功和异步执行失败的后的回调函数。

运行上面代码显而易见,一秒后会执行“经过1s,开始执行”,并调用resolve方法。

到了这里会有很多人开始疑问,这个resolve是什么,也并没有用,并没有执行。

2、resolve的使用

上文提到resolve , reject,分别表示一步操作执行成功和异步执行失败的后的回调函数。 那么Promise函数完毕之后如何让这两个函数执行呢?

执行下面代码:

let any_1 = new Promise((resolve, reject)=> {

setTimeout(()=> {

console.log("1s后执行");

resolve("Promise执行完毕")

}, 1000);

})

any_1.then((data)=> {

console.log(data);

})

控制台LOG:

Promise对象调用then方法,then接收一个函数参数,并且会拿到Promise执行成功回调resolve函数的参数。这即是Promise的作用了。简单来讲,就是能把原来的回调写法分离出来,在异步操作执行完后,用链式调用的方式执行回调函数。

3、链式操作的用法

Promise相对于普通的回调函数(callback)来说从从表面上来说可以简化层层回调的写法,Promise的精髓是“状态”,用维护状态、传递状态的方式来使得回调函数能够及时调用,它比传递callback函数要简单、灵活的多。

下面看一段代码:

/**顺序执行Promise */

private orderGo() {

this.firPromise().then((data)=> {

console.log(data);

return this.secPromise();

})

.then((data)=> {

console.log(data);

return this.thirdPromise();

})

.then((data)=> {

console.log(data);

console.log("三个执行完毕");

})

}

按照顺序,每隔一段时间执行一个异步回调,在firPromise方法中传给resolve的数据,可以再接下来的then方法中拿到,下面运行结果:

firPromise secPromise thirdPromise 三个方法的定义如下:

private firPromise(): Promise{

let result = new Promise((resolve, reject)=> {

setTimeout(function() {

console.log("执行第一个Promise, 500ms");

resolve("第一个执行完毕");

}, 500);

})

return result;

}

private secPromise(): Promise{

let result = new Promise((resolve, reject)=> {

setTimeout(function() {

console.log("执行第二个Promise, 300ms");

resolve("第二个执行完毕")

}, 300);

})

return result;

}

private thirdPromise(): Promise{

let result = new Promise((resolve, reject)=> {

setTimeout(function() {

console.log("执行第三个Promise, 200ms");

resolve("第三个执行完毕")

}, 200);

})

return result;

4、reject的用法

到这里大家应该对Promise有了大概的认知,前面笔者只介绍了resolve的用法,还没有介绍reject的用法,下面通过一个简单的例子来捕捉失败的回调:

private rejectPromise(): Promise{

let result = new Promise((resolve, reject)=> {

let math: number = Math.floor(Math.random() * 10);

if(math >= 5) {

resolve("随机数大于5: " math);

} else {

reject("随机数小于5");

}

})

return result;

}

调用 rejectPromise方法

this.rejectPromise().then( //reject的用法

(data)=> {

console.log(data);

},

(data)=> {

console.log(data);

}

)

上面这段代码,随机数如果大于5代表成功了,反而代表失败了执行reject方法,运行结果有两种:

5、all的用法

Promise的 all 提供并行执行异步操作的能力,并且在所有异步操作执行完毕之后才执行回调。依旧使用上面第一的三个方法,all用法如下:

// -------------all用法---------------

Promise.all([this.firPromise(), this.secPromise(), this.thirdPromise()])

.then((datas)=> {

console.log(datas);

})

// -------------all用法---------------

运行结果:

all方法并行执行三个Promise对象,并把所有异步执行的结果放进一个数组中传递给then,就是上面的datas。

6、在实际开发中的用法

先看一个在Egret上常用的方法getResByUrl的使用:

RES.getResByUrl("resource/assets/egret_icon.png", (data)=> {

let icon: egret.Bitmap = new egret.Bitmap(data);

this.addChild(icon);

}, this, RES.ResourceItem.TYPE_IMAGE);

API中:

function getResByUrl(url: string, compFunc?: Function, thisObject?: any, type?: string): Promise;

可以看到getResByUrl 加载一个路径的图片资源,加载完成后执行comFunc回调函数,通过回调函数加载此图片资源,显示出来。我们可以拆分一下这个步骤,如下:

private urlGetImg() {

let result: Promise= RES.getResByUrl("resource/assets/egret_icon.png");

result.then((data)=> {

let icon: egret.Bitmap = new egret.Bitmap(data);

icon.x = egret.MainContext.instance.stage.stageWidth - icon.width;

this.addChild(icon);

})

}

二者结果相同,都可以通过路径把图片加载出来。

下面另外一个例子,参考Nasus

创建5 * 5个对象,异步依次执行一系列操作,效果如下图。

本次所有行为执行完毕之后,才可以进入下一次操作。使用到tween第三方库,源码如下:

private orderTW() {

for (let i = 0; i < 5; i ) {

for (let j = 0; j < 5; j ) {

let map: egret.Bitmap = new egret.Bitmap(RES.getRes("egret_icon_png"));

map.anchorOffsetX = map.width / 2;

map.anchorOffsetY = map.height / 2;

map.x = map.width * j;

map.y = map.height * i;

this._layer.addChild(map);

this._layer.x = egret.MainContext.instance.stage.stageWidth / 2 - this._layer.width / 2;

this._layer.y = egret.MainContext.instance.stage.stageHeight / 2 - this._layer.height / 2;

}

}

//当前下标

let index: number = 0;

//执行动作的Promise

let twPromise = () => {

console.log(`执行${index}次`);

return new Promise((resolve1, reject) => {

egret.Tween.get(this._layer.getChildAt(index)).to({

rotation: 30

}, 400).to({

rotation: -30

}, 400).to({

alpha: 0

}, 200).call(() => {

resolve1(index );

})

})

}

//切换对象的Promise

let orderPromise = () => {

return new Promise((resolve2, reject) => {

twPromise().then(() => {

if (index < this._layer.numChildren) resolve2(orderPromise())

else resolve2("执行完毕")

})

})

}

orderPromise();

}

定义两个Promise方法,分别为tween动画的twPromise和执行twPromise方法的orderPromise方法,orderPromise在初始的时候执行,执行此方法会调用twPromise方法和twPromise的then方法,其中then方法会调用index ,也就是一个对象执行一系列tween动画后,切换下一个对象,然后通过resolve2(orderPromise())使整个过程走完。

小结

本教程通过初入Promise到完成一个简单的Demo,由浅入深学习了Promise的用法,如果有兴趣也可以学习下catch race的用法。通过本教程,您可以学到以下知识点:

· Promise是什么

· Promise的常用两个函数resolve reject的使用

· 链式操作和all的用法

以上就是Promise的的初级用法详解了,希望可以帮助到开发者们。如果您有任何的意见和建议,欢迎您留言和我们共同交流探讨。

(0)

相关推荐

  • EXCEL中函数的用法讲解

    在用EXCEL中,我们常常用到函数,你知道该如何使用函数吗?不知道的朋友,就看小编我接下来的讲解吧! 函数用法 01 函数名称:SUM SUM是excel函数中最为常用的函数之一,sum函数分别出现在 ...

  • excell表格中函数用法讲解:[3]count的用法

    函数COUNT在计数时,将把数值型的数字计算进去:但是错误值.空值.逻辑值.日期.文字则被忽略. 这里小编说一下COUNT函数的计数用法,让我们快速对单元格进行计数. 操作方法 01 首先打开exce ...

  • linux系统命令make.clean的用法讲解

    先先看一下什么是makefile makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作,因为 makefile就像一个Sh ...

  • Linux中使用ln命令在文件之间建立连接的用法讲解

    在Unix世界里有两个'link'(连接)概念,一般称之为硬连接和软连接.一个硬连 接仅仅是一个文件名.(一个文件可以有好几个文件名,只有将最后一个文件名从 磁盘上删除,才能把这个文件删掉.文件名的个 ...

  • linux命令eval的用法讲解

    linux命令eval的用法讲解

  • excel常用函数有哪些(表格各种函数使用)

    熟练掌握应用了Excel中内置的常用函数,就能解决我们日常学习工作中的绝大多数问题,那些复杂的问题,也都是通过这些函数相互嵌套实现的我们这个系列的教程要累计推出4课20个基础函数的用法讲解,今天我们介 ...

  • 老毛桃怎么用啊 图文讲解老毛桃的用法

    老毛桃是一款制作PE系统的软件,如果遇到系统崩溃了可以用来恢复系统。那么老毛桃怎么用啊?本文就为大家详细讲解老毛桃的用法,希望对大家有一定的帮助! 方法/步骤 1、首先下载软件最新版,然后打开。 2、 ...

  • 实例讲解Debian系的Linux中软件包的安装与管理命令用法

    apt-get用法:apt-get [选项] 命令   apt-get [选项] install|remove pkg1 [pkg2 ...]   apt-get [选项] source pkg1 [ ...

  • 高级搜索指令inurl讲解 inurl命令的作用及用法

    上一次说完了intitle的用法,接下来,我们看看另一个用途广泛的高级搜索指令inurl的作用以及用法. 操作方法 01 inurl可以看成是"in"和"url" ...