Promise

参考:

ECMAScript 6 入门 Promis对象 

 

一  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
        });

 

上一篇:JavaScript Promise学习笔记


下一篇:手写promise