初窥Promise

一 揭开Promise的面纱:什么是Promise?

promise是ES6新增的一个特征,它已被列入ES6的正式规范中

Promise对象可以理解为一次执行的异步操作,使用promise对象之后可 使用一种链式调用的方式来组织代码;让代码更加的直观。也就是说,有了Promise对象,就可以将异步操作以同步的操作的流程表达出来,避免了层层嵌套的回调函数。

举个栗子:

$.ajax(url1, function (data1) {
    // do something
    $.ajax(url2, function (data2) {
        // do something
        ...
    })
})
复制代码

我们在回调中加入我们的后续操作,这样一层一层的嵌套,就形成了可怕的‘回调金字塔’,这种写法不便于维护,也会存在许多隐藏的问题。而Promise就是为了解决些问题产生的。

二 Promise API

1 创建一个Promise

方法一:new Promise

var promise = new Promise(function(resolve, reject) {
    resolve('Hello');
})
console.log(promise);   // Promise{<resolved>: "Hello"}
复制代码

方法二:直接创建

var promise = Promise.resolve('Hello');
console.log(promise);   // Promise{<resolved>: "Hello"}
复制代码

2 Promise.resolve()和Promise.reject()

在介绍它们时,让我们先了解Promise的三个状态,加深我们的理解:分别是pending,fulfilled和rejected 。

pending是对象创建后的初始状态,当对象fulfill(成功)时变为fulfilled,当对象reject(失败)时变为rejected。且只能从pengding变为fulfilled或rejected ,而不能逆向或从fulfilled变为rejected、从rejected变为fulfilled。

Promise.reslove()与Promise.reject()都可直接创建一个Promsie,只是二者的状态不一样:完成与拒绝。

var p1 = Promise.resolve('Hello');
var p2 = Promise.reject('Hello');
console.log(p1);    // Promise{<resolved>: "Hello"}
console.log(p2);    // Promise{<rejected>: "Hello"}
复制代码

3 then()、catch()、finally()

1,then方法可以接收两个参数,且通常都是函数。第一个参数会添加到fulfill时调用的数组中,第二个参数添加到reject时调用的数组中。当promise状态fulfill时,会把resolve(value)中的value值传给调用的函数中,同理,当promise状态reject时,会把reject(reason)中的reason值传给调用的函数。 举个栗子:

var promise = new Promise(function(reslove, reject) {
    setTimeout(() => {
        Math.random() > 0.5 ? reslove('success') : reject('fail');
    }, 1000);
})
console.log(promise);
promise.then((res) => {
    console.log('success ' + res);
}, (err) => {
    console.log('err ' + err);
})
复制代码
当随机数大于0.5时,状态为resove,输出为'success success'
当随机数小于0.5时,状态为reject,输出为'fail fail'
复制代码

基本用法我们知道了,那么then的返回值是什么呢?

then是有返回值的,它返回一个新的Promise(与之前任何一个Promise都不同)。然而这个Promised的行为与then中的回调函数的返回值有关
复制代码

让我们来具体看个例子:

var promise = new Promise((resolve, reject) => {
    resolve('success');
})
.then((res) => console.log(res))
.then(() => {console.log('第二个then')});

// 输出为:
// success
// 第二个then
复制代码

我们发现第一个then里面我们直接打印的res,并没有通过resolve或reject改变状态,按照之前的理解这个时候的状态应该是pending,不应进入第二个then里,但是却进了,那我们手动reject一下会怎样呢?

var promise = new Promise((resolve, reject) => {
    resolve('success');
})
.then((res) => Promise.reject(res))
.then((res) => {console.log('1')}, (res) => {
    console.log(2);
});

// 输出为
// 2
复制代码

我们发现当我们手动reject改变状态之后,就进入到了后面then的reject函数中。

why?这里我们来简单说明下:then返回是一个新的promise,并且这个新的promise默认是接受状态,若想改变状态,我们需手动重置。

2,catch()方法:只要Promsie状态更改为reject或者抛出异常,都会进入catch方法。我们来看一下:

var promise1 = Promise.reject('Hello');
promise1.then((res) => {
    console.log('success' + res);
}).catch((res) => {
    console.log('catch ' + res);     // catch Hello
})
复制代码

then()和catch会创建并返回一个新的promise,这个Promise可以用于实现Promsie链式流程控制。

3,finally()方法,这个方法稍微特殊些,我们直接看例子吧:

var promise = Promise.resolve('Hello');
promise.then((res) => {
    console.log(res);   // Hello
}).finally((res) => {
    console.log('finally');     // finally
    console.log(res);       // undefined
}) 
复制代码

这里我们看到finally里res的输出为undefined,这是为什么呢,为什么没有信息呢?这就是特殊的地方:由于无法知道promise的最终状态,所以finally的回调函数中不接收任何参数,它仅用于无论最终结果如何都要执行的情况。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值