大白话讲解Promise

https://www.cnblogs.com/lvdabao/p/es6-promise-1.html 讲得很好

一、链式操作的用法、resolve() 的用法

    

二、reject的用法


有两种结果:
状态置为fullfiled

image.png

或者
状态置为rejected
image.png

三、catch的用法

我们知道Promise对象实例可以共享 Promise 构造函数上的then、catch、finally等方法,catch和then的第二个参数一样,用来指定reject的回调,用法是这样:

        function getNum() {
            var p = new Promise((resolve, reject) => {
                setTimeout(() => {
                    var num = Math.ceil(Math.random() * 10)  ////生成1-10的随机数
                    num <= 5 ? resolve(num) : reject('数字不符合')
                }, 500)
            })
            return p
        }
        getNum().then(
            (data) => {
                console.log('resolved');
                console.log(data);
            }

            // (reason, data) => {
            //     console.log('rejected');
            //     console.log(reason);
            // }
        ).catch(function (reason) {
            console.log('rejected');  //效果和写在then的第二个参数里面一样。
            console.log(reason);
        })

效果和写在then的第二个参数里面一样。不过它还有另外一个作用:在执行resolve的回调(也就是上面then中的第一个参数)时,如果抛出异常了(代码出错了),那么并不会报错卡死js,而是会进到这个catch方法中。请看下面的代码:

    
image.png

也就是说进到catch方法里面去了,而且把错误原因传到了reason参数中。即便是有错误的代码也不会报错了,这与我们的try/catch语句有相同的功能。

四、all的用法

Promise的all方法提供了并行执行异步操作的能力,并且在所有异步操作执行完后才执行回调。我们仍旧使用上面定义好的fun0(), fun1(), fun2(), fun3()这四个函数,看下面的例子:

  

用Promise.all来执行,all接收一个数组参数,里面的值最终都算返回Promise对象。这样,三个异步操作的并行执行的,等到它们都执行完后才会进到then里面。那么,三个异步操作返回的数据哪里去了呢?都在then里面呢,all会把所有异步操作的结果放进一个数组中传给then,就是上面的results。所以上面代码的输出结果就是:


image.png

有了all,你就可以并行执行多个异步操作,并且在一个回调中处理所有的返回数据,是不是很酷?有一个场景是很适合用这个的,一些游戏类的素材比较多的应用,打开网页时,预先加载需要用到的各种资源如图片、flash以及各种静态文件。所有的都加载完后,我们再进行页面的初始化。

五、race的用法

all方法的效果实际上是「谁跑的慢,以谁为准执行回调」,那么相对的就有另一个方法「谁跑的快,以谁为准执行回调」,这就是race方法,这个词本来就是赛跑的意思。race的用法与all一样,我们把上面fun0(), fun1(), fun2(), fun3()的延时改一下来看一下:

    

requestImg函数会异步请求一张图片,我把地址写为"xxxxxx",所以肯定是无法成功请求到的。timeout函数是一个延时5秒的异步操作。我们把这两个返回Promise对象的函数放进race,于是他俩就会赛跑,如果5秒之内图片请求成功了,那么遍进入then方法,执行正常的流程。如果5秒钟图片还未成功返回,那么timeout就跑赢了,则进入catch,报出“图片请求超时”的信息。运行结果如下:


image.png

六、总结

ES6 Promise的内容就这些吗?是的,能用到的基本就这些。
我怎么还见过done、finally、success、fail等,这些是啥?这些并不在Promise标准中,而是我们自己实现的语法糖。

本文中所有异步操作均以setTimeout为例子,之所以不使用ajax是为了避免引起混淆,因为谈起ajax,很多人的第一反应就是jquery的ajax,而jquery又有自己的Promise实现。如果你理解了原理,就知道使用setTimeout和使用ajax是一样的意思。说起jquery,我不得不吐槽一句,jquery的Promise实现太过垃圾,各种语法糖把人都搞蒙了,我认为Promise之所以没有全面普及和jquery有很大的关系。后面我们会细讲jquery。

关于Promise还有一些内容是需要讲的,限于篇幅,本文就只作ES6 Promise的讲解,接下来还会有大白话讲解系列:
Promise/A+规范
jquery中的Promise

敬请期待!

你可能感兴趣的:(大白话讲解Promise)