参考:
一 Promise定义
二 Promise基本应用
三 Promise的错误处理
四 使用await直接获得resolve结果
五 Promise.resoleve
Promise定义
Promise是异步编程解决方案,比传统回调函数和事件的解决方案更合理。
举个例子,分别进行通用资源,配置,场景的加载,加载完成后进入游戏。
如果使用回调函数来进行异步加载操作,会有比较多的嵌套,如下:
start() { this.loadRes(() => { this.loadConfig(() => { this.loadScene(() => { //todo 全部加载完成,进入游戏 }, this); }, this) }, this); } //加载通用资源 loadRes(callback, target) { setTimeout(() => { console.log("加载通用资源成功"); callback.call(target); }, 1000); } //加载配置 loadConfig(callback, target) { setTimeout(() => { console.log("加载配置成功"); callback.call(target); }, 1000); } //加载场景 loadScene(callback, target) { setTimeout(() => { console.log("加载场景成功"); callback.call(target); }, 1000); }
使用Promise,没有了回调嵌套,可以同步书写方式表达出程序执行的流程。
async start () { await this.loadRes(); await this.loadConfig(); await this.loadScene(); //todo 全部加载完毕,进入游戏 } //加载通用资源 async loadRes(){ return new Promise((resolve, reject)=>{ setTimeout(()=>{ console.log("加载通用资源成功"); resolve(true); }, 1000); }); } //加载配置 async loadConfig(){ return new Promise((resolve, reject)=>{ setTimeout(()=>{ console.log("加载配置成功"); resolve(true); }, 1000); }); } //加载场景 async loadScene(){ return new Promise((resolve, reject)=>{ setTimeout(()=>{ console.log("加载场景成功"); resolve(true); }, 1000); }); }
Promise基本应用
resolve和reject是JavaScript引擎自带的Promise构造函数参数。
resolve 将Promise状态由pending(进行中)变成fulfilled(已成功),并将操作结果传递出去。
reject 将Promise状态由pending(进行中)变成rejected(已失败),并将操作结果传递出去。
then方法是接收resolve和reject状态的回调函数,写法是 then(()=>{}, ()=>{}),前一个resolve回调函数,后一个reject回调函数。
例如现在加载一张图片,new一个Promise进行异步加载,使用then方法处理加载成功和失败操作。
let promise = new Promise((resolve, reject)=>{ setTimeout(()=>{ if(0){ resolve(1); }else{ reject("10.png"); } },1000) }); promise.then((value)=>{ console.log("加载成功:", value); //加载成功,输出 1 },(value)=>{ console.log("加载失败,失败资源名:", value); //加载失败,输出10.png });
Promise的错误处理
catch用于发生错误时的回调函数。下面两行代码功能一样,then的第二个函数和catch都能够处理reject。
//代码功能一样。 promise.then((value)=>{},(value)=>{}); promise.then((value) => {}).catch((value) => {});
建议使用catch,而不是使用then的第二函数来处理失败reject。
1. Promise错误具有"冒泡"性质,会一直传递,直到被捕获。所以错误总能被下一个catch所捕获。例如链式使用3个Promise,任何一个Promise的错误都能被最外面那个catch捕获。
getJSON('/post/1.json').then(function(post) { return getJSON(post.commentURL); }).then(function(comments) { // some code }).catch(function(error) { // 处理前面三个Promise产生的错误 });
2. catch更接近同步try/catch的写法,比then的第二个函数写法更容易理解和阅读。
使用await直接获得resolve结果
await配合Promise使用,在resolve时,能够直接获得resolve传递的参数。在reject时,获得的始终是undefined。
async start() { let a = await this.test(); console.log(a); //成功时输出a=1;失败时a=undefined } async test(){ return new Promise((resolve, reject)=>{ if(0){ resolve(1); }else{ reject(2); } }).catch((err)=>{console.log(err)}); //成功时,不执行catch;失败时,err=2 }
Promise.resoleve
快速创建一个resolved状态的Promise。 Promise.reject()同理。
let promise = Promise.resolve(1); promise.then((value)=>{ console.log(value); //输出1 });