资讯专栏INFORMATION COLUMN

总结一下ES6的promise

Bowman_han / 2350人阅读

摘要:代码结果是原因是或者中一个对象并不会抛出错误,而是通过来处理的,所以不会被后续的捕获,需要改成其中一种方法方法是的语法糖,用于指定发生错误时的回调函数。

基本用法

promise有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败),Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolve和reject,其中resolve函数会将pending状态改为fulfilled,reject函数将pending改为rejected状态,状态一旦改变,将不可逆。这两个函数的函数的参数将会传给回调函数

const promise = new Promise(function(resolve, reject) {
        // ... some code

        if (/* 异步操作成功 */){
            resolve(value);
        } else {
            reject(error);
        }
    });
    promise.then((value)=>{ 
        console.log(value)
    },(error)=>{
        console.log(error)
    })
then方法

Promise实例生成以后,可以用then方法分别指定resolved状态和rejected状态的回调函数,第一个是状态由pending->fulfilled的回调,第二个是pending->resolved的回调。
then为什么可以进行链式调用呢?原因就是then方法返回的也是一个promise对象,所以后面可以继续使用then()方法。
此处有个地方需要注意,着重理解下面这句话:
Values returned from the onFulfilled or onRejected callback functions will be automatically wrapped in a resolved promise.
then()的两个参数函数中返回的值,会自动包装成一个已resolved的promise。
代码1:

$http({
            method: "GET",
            url: "https://www.runoob.com/try/angularjs/data/sites.php1"
        }).then(function successCallback(data_1) {
            $scope.res = data_1;
            $scope.names = data_1.data.sites;
            return data_1;
        },function (err_1) {
            console.log("err_1",err_1);
            return err_1;
        }).then(function (data_2) {
            console.log("data_2", data_2)
        },function (err_2) {
            console.log("err_2---->",err_2);
        }).catch(function (reason) {
            console.log("err------->",reason);
        });

注:$http返回的是一个promise对象。
结果如下:

网络请求404->失败的回调函数err_1方法->成功的回调函数(why),原因就是then中的回调函数,无论是成功回调还是失败回调,他们return的值都会被包装成promise的对象的resolved函数来处理,从而会传递给下一个then方法的成功回调函数里面去。
代码2:

Promise.resolve()
        .then(() => {
            return new Error("error!!!")
        })
        .then((res) => {
            console.log("then: ", res)
        })
        .catch((err) => {
            console.log("catch: ", err)
        })

结果是:

then: Error: error!!!
at Promise.resolve.then (...)
at ...

原因是:.then 或者 .catch 中 return 一个 error 对象并不会抛出错误,而是通过resolved来处理的,所以不会被后续的 .catch 捕获,需要改成其中一种:

1.return Promise.reject(new Error("error!!!"))
2.throw new Error("error!!!")
catch方法

Promise.prototype.catch方法是.then(null, rejection)的语法糖,用于指定发生错误时的回调函数。
1.then方法中没有第二个失败回调函数,当reject后,会进入catch方法;若then方法有第二个失败
回调,则reject后会进入此函数,而不会进入catch方法。

$http({
            method: "GET",
            url: "https://www.runoob.com/try/angularjs/data/sites.php"
        }).then(function successCallback(data_1) {
            $scope.res = data_1;
            $scope.names = data_1.data.sites;
            return data_1;
        },function (err_1) {
            console.log("err_1",err_1);
            return err_1;
        }).catch(function (reason) {
            console.log("err------->",reason);
        });

结果:

当没then有第二个回调函数,则会进入catch方法。
小疑问:catch方法中return一个数值,在其后面的.then()的成功回调中会接收到么?答案是会的,把catch看做成没有成功回到的.then(),其return的数值也会被resolved出去。
注意:不要在then方法里面定义 Reject 状态的回调函数(即then的第二个参数),总是使用catch方法。理由是第二种写法可以捕获前面then方法执行中的错误,也更接近同步的写法(try/catch)

// bad
promise
  .then(function(data) {
    // success,标记1.要是在此处代码抛出了错误,此then函数的失败回调函数是捕捉不到的。
  }, function(err) {
    // error
  });

// good
promise
  .then(function(data) { //cb
    // success
  })
  .catch(function(err) {
    // error
  });

即:如果在“标记1”出代码抛出错误,后面的失败回调函数是捕捉不到的(只能捕捉上一个promise对象抛出的错误,自己所处在的then中是捕捉不到的),而只能被下一个then函数的失败回调(也就是catch)捕捉到。
例子:

Promise.resolve()
        .then(function success (res) {
            throw new Error("error")
        }, function fail1 (e) {
            console.error("fail1: ", e)
        })
        .catch(function fail2 (e) {
            console.error("fail2: ", e)
        })
    

结果:

fail2: Error: error
at success (...)
at ...

.then 可以接收两个参数,第一个是处理成功的函数,第二个是处理错误的函数。.catch 是 .then 第二个参数的简便写法,但是它们用法上有一点需要注意:.then 的第二个处理错误的函数捕获不了第一个处理成功的函数抛出的错误,而后续的 .catch 可以捕获之前的错误
以下代码也可以:

Promise.resolve()
        .then(function success1 (res) {
            throw new Error("error")
        }, function fail1 (e) {
            console.error("fail1: ", e)
        })
        .then(function success2 (res) {
        }, function fail2 (e) {
            console.error("fail2: ", e)
        })

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/94764.html

相关文章

  • ES6-7

    摘要:的翻译文档由的维护很多人说,阮老师已经有一本关于的书了入门,觉得看看这本书就足够了。前端的异步解决方案之和异步编程模式在前端开发过程中,显得越来越重要。为了让编程更美好,我们就需要引入来降低异步编程的复杂性。 JavaScript Promise 迷你书(中文版) 超详细介绍promise的gitbook,看完再不会promise...... 本书的目的是以目前还在制定中的ECMASc...

    mudiyouyou 评论0 收藏0
  • ES6精解:promise用法

    前言 今天就简单总结一下promise的用法,在用promise之前,我们要先了解一下什么promise,这个东西是用来干什么的? 通俗易懂的讲,promise其实就是一个构造函数,是用来解决异步操作的,我们平时其实还是会用到挺多的,比如我们经常会嵌套一层层的函数 step1(function (value1) { step2(value1, function(value2){ s...

    enali 评论0 收藏0
  • ES6常用知识点概述

    摘要:那之前的例子来使用一下的话,你会发现浏览器报错了,如图定义的变量不允许二次修改。如图箭头函数没有它自己的值,箭头函数内的值继承自外围作用域。如图这里两边的结构没有一致,如果是的话,是可以正常解构的。 前言 国庆假期已过一半,来篇干货压压惊。 ES6,并不是一个新鲜的东西,ES7、ES8已经赶脚了。但是,东西不在于新,而在于总结。每个学前端的人,身边也必定有本阮老师的《ES6标准入门》或...

    keithyau 评论0 收藏0
  • ES6Promise:要优雅,也要浪漫

    摘要:就算改变已经发生了,即使再对对象添加回调函数,也会立即得到这个结果。方法接收个参数,第一个参数是状态的回调函数,第二个参数可选是状态的回调函数。简单来讲,就是能把原来的回调写法分离出来,在异步操作执行完后,用链式调用的方式执行回调函数。 在ECMAScript 6标准中,Promise被正式列为规范,Promise,字面意思就是许诺,承诺,嘿,听着是不是很浪漫的说?我们来探究一下这个浪...

    weizx 评论0 收藏0
  • JS笔记

    摘要:从最开始的到封装后的都在试图解决异步编程过程中的问题。为了让编程更美好,我们就需要引入来降低异步编程的复杂性。异步编程入门的全称是前端经典面试题从输入到页面加载发生了什么这是一篇开发的科普类文章,涉及到优化等多个方面。 TypeScript 入门教程 从 JavaScript 程序员的角度总结思考,循序渐进的理解 TypeScript。 网络基础知识之 HTTP 协议 详细介绍 HTT...

    rottengeek 评论0 收藏0

发表评论

0条评论

Bowman_han

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<