ES6的promise使用说明书

简介: 好几天前就想写一个promise的笔记了,但是一直以来就仅仅知道它是用来解决回调地狱问题的,没有一个详细的了解,所以在这几天学习的时候,针对它名下的几个方法,做了一个简要的使用介绍。

前言

好几天前就想写一个promise的笔记了,但是一直以来就仅仅知道它是用来解决回调地狱问题的,没有一个详细的了解,所以在这几天学习的时候,针对它名下的几个方法,做了一个简要的使用介绍。

promise:这就是我的说明书!

我:可能说的不是太全,多包涵~

先来了解一下它

什么是promise?它是一个类?一个对象?一个数组?

我们先打印它来看一看吧:

console.dir(Promise);

认识promise.png

打印完了,我们来正式认识一下它。

promise是一个构造函数,是ES6提出的异步编程解决方案,用来解决回调地狱这种问题,从打印可以看出,它有rejectallresolve等方法,它的原型上有catchthen等方法。

还有一种说法来自于网络: promise,意为承诺,承诺过一段时间给你结果。promise有三种状态,分别为pending(等待),fulfiled(成功),rejected(失败),状态一旦经过改变,就不会在变。

// fn1执行,如果a>10 执行fn2 ,如果a == 11,执行fn3

function fn1(a, fn2) {
    if (a > 10 && typeof fn2 == 'function') {
        fn2(a,function(){
            if(a == 11){
                console.log('this is fn3')
            }
        })
    }
}
fn1(11, function(a, fn3) {
    console.log('this is fn2')
    fn3()
})

上面说了promise的提出是用来解决回调地狱的问题,那么什么是回调地狱呢?可以参考一下我这段代码,不断的嵌套回调函数之后,代码就会变得非常繁琐,看代码的时候眼睛不舒服,脑子也不舒服,这种嵌套回调非常多的情况,就叫做回调地狱

如何使用promise

var p = new Promise(function(resolve, reject){
    //做一些异步操作
    setTimeout(function(){
        console.log('执行完成');
        resolve('写啥都行');
    }, 3000);
});

Promise的构造函数接收一个function,并且这个函数需要传入两个参数:

  • resolve :异步操作执行成功后的回调函数
  • reject:异步操作执行失败后的回调函数

then

还记得上面我写的那个嵌套非常多的例子吗?啊,不记得,那你翻一翻~

Promise的优势就在于,可以在then方法中继续写Promise对象并返回,然后继续调用then来进行回调操作。

所以,从表面上看,Promise只是能够简化层层回调的写法,而实质上,Promise的精髓是状态,用维护状态、传递状态的方式来使得回调函数能够及时调用,它比传递callback函数要简单、灵活的多。所以使用Promise的正确场景是这样的:

function fn1(a){
    var p = new Promise(function(resolve, reject){
        //做一些异步操作
           resolve(a);
    });
    return p;            
}
fn1(11)
.then(function(a){
    return new Promise(function(resolve, reject){
        if(a > 10){
               console.log('a大于10')
           }
           resolve(a);
    })
})
.then(function (a){
    if(a == 11){
        console.log('a等于11')
    }
})
我将上面那个改写了一下。最后那个没有return出来是我后面没有继续then了。

这其实就是链式写法。then就相当于我们之前的callback。

then方法中,不光可以return promise对象,也可以return数据:

function fn1(a){
    var p = new Promise(function(resolve, reject){
        //做一些异步操作
           resolve(a);
    });
    return p;            
}
fn1(11)
.then(function(a){
        if(a > 10){
               console.log('a大于10')
           }
           return a
})
.then(function (a){
    if(a == 11){
        console.log('a等于11')
    }
})

reject

把promise的状态从pending改成rejected,之后我们就可以在then中执行失败情况的回调,来看这个例子:

function fn1(a){
    var p = new Promise(function(resolve, reject){
           if(a>10){
               resolve(a);
           }else {
               reject(a);
           }
    });
    return p;            
}
fn1(9)
.then((a) => {
    console.log('a大于10')
},    (err) => {
    console.log('a小于10')
})

then可以接收两个参数,分别对应着resolve的回调和reject的回调,所以在调整传入的a的值,我们可以得到两个结果。

即a大于10和a小于10

catch

对其他语言有了解的人应该可以知道,catch是用来抓取异常的,那么在promise里,它的作用也一样,它就如同then的第二个参数,对应着reject的回调

写法是这样:

.then((a) => {
    console.log('a大于10')
}).catch((err) => {
    console.log('a小于10')
})

效果和写在then的第二个参数里面是一样的。

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

就很像 try catch

再来看这段代码

function fn1(a){
    var p = new Promise(function(resolve, reject){
        //做一些异步操作
           resolve(a);
    });
    return p;            
}
fn1(11)
.then(function(a){
        if(a > 10){
               console.log('a大于10')
           }
           return b
})
.catch(function (err){
    console.log('发生了错误:' + err)
})

这段代码中 本来想return a的 结果写成了b,正常来说浏览器会报错,不会向下执行了,在我们用了catch后,

浏览器会打印出a大于10发生了错误:ReferenceError: b is not defined

也就是说即使是上面出错了,还是进到catch方法里面去了,而且把错误原因传到了err参数中,使得程序继续执行下去。

all

all方法提供了多个任务并行,执行异步操作的能力,并且在所有异步操作执行完后才执行回调。

  • all方法接收的参数是一个数组,其中每个都是promise对象
let p = Promise.all([fn1, fn2, fn3])

p.then(funciton(){
  // 三个都成功则成功  
}, function(){
  // 只要有一个失败,则失败 
})

有了all,我们就可以并行执行多个异步操作,有一个场景是很适合用这个的,打开一个网页,需要加载各类资源,所有的都加载完后,再进行页面的初始化。

race

all方法的效果实际上是谁跑的慢,以谁为准执行回调,那么相对的就有另一个方法谁跑的快,以谁为准执行回调,这就是race方法。

拿上面的fn123举例子,假如他们分别是1、2、3秒执行完,那么在第一秒结束的时候就会输出fn1执行后的结果,在两秒跟三秒的时候会分别输出fn2、fn3的结果。

这个race有什么用呢?使用场景还是很多的,比如我们可以用race给某个异步请求设置超时时间,并且在超时后执行相应的操作。

例如图片请求,我们将一个延迟请求(假如是3秒)跟图片请求同时使用race方法调用,在3秒的时候如果请求成功了,就会resolve进入then方法,如果失败了就会进入catch方法输出图片资源请求失败的错误。

最后

十一的假期结束了,上学人又要继续上课了,害。

点个赞,一起努力进步吧♥
相关文章
|
5月前
|
前端开发 JavaScript 测试技术
ES6:什么是Promise?
ES6:什么是Promise?
44 0
|
5月前
|
前端开发 小程序 JavaScript
es6读书笔记(五)Promise
es6读书笔记(五)Promise
|
5月前
|
前端开发 JavaScript 测试技术
ES6:什么是Promise
ES6:什么是Promise
|
17天前
|
前端开发 JavaScript
ES6新标准下JS异步编程Promise解读
ES6新标准下JS异步编程Promise解读
23 3
|
2月前
|
前端开发
手写实现ES6的Promise.all()和Promise.race()函数
这篇文章介绍了如何手写实现ES6的`Promise.all()`和`Promise.race()`函数,提供了实现这两个Promise聚合函数的详细代码示例,并展示了如何使用它们。
手写实现ES6的Promise.all()和Promise.race()函数
|
3月前
|
前端开发 JavaScript
ES6 中 Promise对象使用学习
ES6 中 Promise对象使用学习
33 1
|
2月前
|
前端开发 JavaScript
ES6新特性(五):Promise优雅地处理异步
ES6新特性(五):Promise优雅地处理异步
|
4月前
|
JSON 前端开发 JavaScript
ES6引入Promise和async/await解决异步问题
【6月更文挑战第12天】ES6引入Promise和async/await解决异步问题。Promise处理异步操作,有pending、fulfilled、rejected三种状态,支持链式调用和并行处理。async/await是基于Promise的语法糖,使异步代码更同步化,提高可读性。两者都是处理回调地狱的有效工具,开发者应根据需求选择合适的方式。
50 3
|
5月前
|
前端开发 JavaScript
ES6:Promise使用方法解析大全
ES6:Promise使用方法解析大全
|
5月前
|
资源调度 前端开发 JavaScript
vue - ES6模块化、promise、webpack打包(所在在学的朋友们先看这篇,看了不吃亏)...
vue - ES6模块化、promise、webpack打包(所在在学的朋友们先看这篇,看了不吃亏)...