美文网首页
ES6 Promise的理解

ES6 Promise的理解

作者: 别过经年 | 来源:发表于2017-04-17 13:51 被阅读867次

首先看下ES6的Promise接口:

interface Promise<T> {
    /**
     * Attaches callbacks for the resolution and/or rejection of the Promise.
     * @param onfulfilled The callback to execute when the Promise is resolved.
     * @param onrejected The callback to execute when the Promise is rejected.
     * @returns A Promise for the completion of which ever callback is executed.
     */
    then<TResult1, TResult2>(onfulfilled: (value: T) => TResult1 | PromiseLike<TResult1>, onrejected: (reason: any) => TResult2 | PromiseLike<TResult2>): Promise<TResult1 | TResult2>;

    /**
     * Attaches callbacks for the resolution and/or rejection of the Promise.
     * @param onfulfilled The callback to execute when the Promise is resolved.
     * @param onrejected The callback to execute when the Promise is rejected.
     * @returns A Promise for the completion of which ever callback is executed.
     */
    then<TResult>(onfulfilled: (value: T) => TResult | PromiseLike<TResult>, onrejected: (reason: any) => TResult | PromiseLike<TResult>): Promise<TResult>;

    /**
     * Attaches callbacks for the resolution and/or rejection of the Promise.
     * @param onfulfilled The callback to execute when the Promise is resolved.
     * @returns A Promise for the completion of which ever callback is executed.
     */
    then<TResult>(onfulfilled: (value: T) => TResult | PromiseLike<TResult>): Promise<TResult>;

    /**
     * Creates a new Promise with the same internal state of this Promise.
     * @returns A Promise.
     */
    then(): Promise<T>;

    /**
     * Attaches a callback for only the rejection of the Promise.
     * @param onrejected The callback to execute when the Promise is rejected.
     * @returns A Promise for the completion of the callback.
     */
    catch<TResult>(onrejected: (reason: any) => TResult | PromiseLike<TResult>): Promise<T | TResult>;

    /**
     * Attaches a callback for only the rejection of the Promise.
     * @param onrejected The callback to execute when the Promise is rejected.
     * @returns A Promise for the completion of the callback.
     */
    catch(onrejected: (reason: any) => T | PromiseLike<T>): Promise<T>;
}

发现无论是catch的参数还是then的第二个参数,都叫onrejected

下面是我的测试代码:

function c() {
    return new Promise((resolve, reject) => {
        console.info('begin do something');
        setTimeout(() => {
            // resolve("result");
            reject("reject");
        }, 2000);
        // throw new Error("悲剧了");
    });
}

// c().catch((err) => {     console.info(err); });

c().then((ret) => {
    console.info(ret);
}).catch((err) => {
    console.info(err);
});
  1. 只要有throw new Error("悲剧了");就会走then的第二个参数或者catch,这取决于有then有没有第二个参数,有的话就走then的第二个参数,没有的话就走catch,
    then的第二参数的优先级比catch高,
function c() {
    return new Promise((resolve, reject) => {
        console.info('begin do something');
        // setTimeout(() => {     // resolve("result");     reject("reject"); }, 2000);
        reject("reject");
        throw new Error("悲剧了");
    });
}

这样的话输出就是 reject

Promise中resolve和reject不能同时执行,二选一,

then的优先级比catch高,所以一般在then中写第二个参数,不写catch就可以了。

我用的是vscode 写的 ts文件 配置task.json去编译ts到js 然后调试就方便了

Javascript的异步编程:Promise
Javascript 中的神器——Promise

vue中如何让第一个事件执行完之后再执行下一个事件?

一个小伙伴的提问:

fn1(){
    fn2();
    fn3();
}

怎样做才能使fn2执行完之后再执行fn3?

回答
同步的话可以这么写,异步这么写好像行不通

!function () {
    var fn2 = function () {
        return Promise.resolve("fn2")
    }
    var fn3 = function () {
        return Promise.resolve("fn3")
    }
    void function fn1() {
        fn2().then(function (val) {
            console.info(val);
            return fn3();
        }).then(function (val) {
            console.info(val);
        });
    }()
}()

异步写法:

!function () {
    var fn2 = function () {
        return new Promise(function (resolve, reject) {
            setTimeout(function () {
                resolve("fn2");
            }, 1000);
        });
    }
    var fn3 = function () {
        return new Promise(function (resolve, reject) {
            setTimeout(function () {
                resolve("fn3");
            }, 1000);
        })
    }
    void function fn1() {
        fn2().then(function (val) {
            console.info(val);
            return fn3();
        }).then(function (val) {
            console.info(val);
        });
    }()
}()

axios 异步请求的封装:

项目中用到封装一个请求函数,在后面每个vue组件中都可以调用,回调的话在一个组件中调用父组件的this.request()后,子组件拿不到请求完成或者失败的状态,所以这个时候需要promise来解决这个问题。
模拟ajax

function request(status) {
    return new Promise(function (resolve, reject) {
        if (status === 200 || status === 400) {
            resolve({ errCode: status, data: 88 })
        } else {
            reject({ errCode: status, data: 88 });
        }
    }).then(function (res) {//请求后,后台返回的数据
        // if (res.errCode === 200) {
        //     return Promise.resolve(res.data);
        // } else {
        //     return Promise.reject(res.data);
        // }

        return new Promise(function (resolve, reject) {
            if (res.errCode === 200) {
                return resolve(res.data);
            } else {
                return reject(res.data);
            }
        });
    }, function (err) {
        return err;
    });
}

request(400).then(function (data) {
    console.info(data);
}, function (err) {
    console.info(err);
});

第一个new promise是模拟ajax请求,后台返回有不同的status状态,一般200的话是请求成功,并且得到正确的数据,而其他的请求即使成功,走的是then的第一个函数,status是不同的状态码,有些状态码需要在公共的方法中处理,就是在这里处理,有些需要到每个组件的then里面处理,axios的错误状态捕获有,可以在then的第二个参数中捕获,或者在catch里面捕获,then第二个参数的优先级高于catch,所以处理一个就行了,上面代码是then里面处理异常,也可以在catch处理:

function invoke(res) {
    return Promise.resolve(res)
        .then(res => {
            console.log(res += '!');
            return res;
        })
        .then(res => {
            console.log(res += '!');
            return Promise.reject("end"); //此处返回了一个新的promise
        })
        .catch(res => {
            console.log(res);
            // return res;  //此处也返回了一个新的resolved的promise
            return Promise.reject(res);//此处返回一个新的rejected的promise
        })
        .then(res => {
            console.log(res += '!');  //肯定会执行了
        }, err => {
            console.info(err += '!');
        });
}
invoke('hello');
// hello!
// hello!!
// end
// end!

从接口也可以看出来,catch是可以再次返回promise的。

/**
     * Attaches a callback for only the rejection of the Promise.
     * @param onrejected The callback to execute when the Promise is rejected.
     * @returns A Promise for the completion of the callback.
     */
    catch(onrejected?: ((reason: any) => T | PromiseLike<T>) | undefined | null): Promise<T>;

    /**
     * Attaches a callback for only the rejection of the Promise.
     * @param onrejected The callback to execute when the Promise is rejected.
     * @returns A Promise for the completion of the callback.
     */
    catch<TResult>(onrejected: (reason: any) => TResult | PromiseLike<TResult>): Promise<T | TResult>;

实际项目中:

 return axios(config).then(response => {
    var res = response.data;
    var promise = new Promise((resolve, reject) => {
      if (res.status !== 1) {
        reject(res);
      } else {
        resolve(res);
      }
    })
    return promise;
  }, err => {
    return Promise.reject(err);//1.超时的话,
  }).catch((exp) => {
    console.info("exception:", exp);//2.
    return Promise.reject(exp);
  });

login.vue

      this.$http('student/login', "post", form).then((res) => {
        localStorage.setItem("token", res.token);
        this.$router.push("/index");
      }, (err) => {
        console.info("login err");//并不会走这里
      }).catch(exp => {
        console.info(exp);//3.
      });

删除一些配置:

  return axios(config).then(response => {
    var res = response.data;
    var promise = new Promise((resolve, reject) => {
      if (res.status !== 1) {
        reject(res);
      } else {
        resolve(res);
      }
    })
    return promise;
  }, err => {
    return Promise.reject(err);//1.超时
  });

login.vue

      this.$http('student/login', "post", form).then((res) => {
        localStorage.setItem("token", res.token);
        this.$router.push("/index");
      }, (err) => {
        console.info("login err");//并不会走这里,可能和axios这个库有关系
      });

最后改进为两边都使用catch捕获:

  return axios(config).then(response => {
    var res = response.data;
    var promise = new Promise((resolve, reject) => {
      if (res.status !== 1) {
        reject(res);
      } else {
        resolve(res);
      }
    })
    return promise;
  }).catch((exp) => {
    console.info("exception:", exp);
    return Promise.reject(exp);
  });

login.vue

    this.$http('student/login', "post", form).then((res) => {
        localStorage.setItem("token", res.token);
        this.$router.push("/index");
      }).catch(exp => {
        console.info(exp);
      });

ES6 Promise Catch后面的then还是会执行?

相关文章

  • Promise对象原理解析

    Promise对象原理解析 ES6 原生提供了 Promise 对象。所谓 Promise,就是一个对象,用来传递...

  • Promise的理解和使用

    Promise是什么? 理解 1. 抽象表达 Promise是一门新的技术(ES6规范) Promise是JS中进...

  • 全局 Promise 异常捕捉

    《深入理解ES6》阅读随笔 在 ES6 的 Promise 中,对于直接 reject 的异常未处理任务,不会进行...

  • ES6 中的 Promise(三)

    《深入理解ES6》阅读随笔 响应多个 Promise 在 Promise 中还有两个静态方法,可以用来控制响应多个...

  • ES6--Promise

    学过ES6的同学大概都知道Promise,可想而知Promise在ES6中很重要。 Promise对象代表了未来将...

  • es6解读5:promise

    Promise作为ES6中最重要的特性之一,我们有必要掌握并理解透彻。本文将由浅到深,讲解Promise的基本概念...

  • 解析Promise

    Promise作为ES6中最重要的特性之一,我们有必要掌握并理解透彻。本文将由浅到深,讲解Promise的基本概念...

  • es6解读5-promise

    Promise作为ES6中最重要的特性之一,我们有必要掌握并理解透彻。本文将由浅到深,讲解Promise的基本概念...

  • ES6 中的 Promise(二)

    《深入理解ES6》阅读随笔 对于 Promise 中的一些基础概念,需要了解一下: Promise 的生命周期 P...

  • Promise.done(),Promise.finally()

    es6 Promise.done(),Promise.finally()promise对象的finally函数为什...

网友评论

      本文标题:ES6 Promise的理解

      本文链接:https://www.haomeiwen.com/subject/ohdtzttx.html