promise用法

使用背景

这里只讲promise的如何使用,适用于什么情况下。不手撕源码,想看手撕源码请移步B站搜索promise。
假设我们现在有一串代码,用来判断现在输入的字符换是不是“abcd”。这段代码比较傻,只会一个字符换一个字符串的判断。

function check(str){
    if (str[0]=='a'){
        if (str[1]=='b'){
            if (str[2]=='c'){
                if (str[3]=='d'){
                    if (str[4]== undefined ){
                        console.log("这个字符串就是abcd")
                    }
                    else{
                        console.log("该字符串不是abcd")
                    }   
                } 
                else{
                    console.log("该字符串不是abcd")
                }  
            }
            else{
                console.log("该字符串不是abcd")
            }
        }
        else{
            console.log("该字符串不是abcd")
        }
    }   
    else{
        console.log("该字符串不是abcd")
    }
}


这里可以看到,这里有很多if,else嵌套。因为只是判断字符所以代码看起来还是比较规律的。这是同步的程序,如果是异步的还带有回调函数的代码,代码的可读性就不是那么高了。

promise初探

promise对象有三种状态分别是

  • pending
  • resolved(fulfilled)
  • rejected

我们可以使用var 对象名 = new Promise(function(resolve,rejected)) 的方式生成promise对象。function(resolve,rejected)称为执行函数
生成对象的过程中,如果一直不使用resolve或者reject函数来设置promise的状态,那么promise对象将一直为pending状态。

var temp = new Promise(function(resolve,reject) {
        
})
console.log(temp)
//[[PromiseStatus]]: "pending"
//[[PromiseValue]]: undefined

如果使用resolve函数,那么promise对象就变成了fulfilled状态了。

var temp = new Promise(function(resolve,reject) {
        resolve('调用了resolve函数')
})
console.log(temp)
//[[PromiseStatus]]: "fulfilled"
//[[PromiseValue]]: "调用了resolve函数

同理使用了reject函数,promise对象就变成了rejected状态

var temp = new Promise(function(resolve,reject) {
        reject('调用了reject函数')
})
console.log(temp)
//[[PromiseStatus]]: "rejected"
//[[PromiseValue]]: "调用了reject函数"

then()函数

then函数的用法:promise对象.then(fulfilled状态对应的函数,rejected状态对应的函数)

百度抄的定义:第一个then不管是走成功还是失败的回到函数,只要返回一个普通值(不抛出错误或者返回promise),都会执行下一个then的成功的回调。---------------------我的理解是,不使用throw抛出错误或者返回一个promise对象,下一个then就调用resolve对应的函数,反之调用rejecte对应的函数。
当peomise对象是fulfilled状态,就会调用fulfilled状态对应的函数。
同理当peomise对象是rejected状态,就会调用rejected状态对应的函数。

总结:
使用resolve对应函数的两种情况1、promise对象为resolved状态且第一次调用then 2、前一个then返回的不是promise对象或抛出错误。
使用resolve对应函数的两种情况1、promise对象为rejected状态且第一次调用then 2、前一个then返回的是promise对象或抛出错误。

var temp = new Promise(function(resolve,reject) {
    resolve('调用了resolve函数')//这里使用了resolve所以promise就变成了fulfilled
})
temp
.then(
    function(data) {
        console.log(data)		//输出为 “调用了resolve函数” 时第二行调用resolve函数的时候将值放入PromiseValue中了
        console.log('promise调用了resolve函数')//该行输出
    },
    function(data) {//该函数不执行,因为promise对象不是rejeted状态
        console.log(data)
        console.log('promise调用了reject函数')
    }
)

当peomise的状态时pending的时候,then函数不会执行。

var temp = new Promise(function(resolve,reject) {
    // resolve('调用了resolve函数')
})
a = temp
.then(
    function(data) {//该函数不执行
        console.log(data)
        console.log('promise调用了resolve函数')
    },
    function(data) {//该函数不执行
        console.log(data)
        console.log('promise调用了reject函数')
    }
)

且个人建议使用then的时候返回对象为promise对象,这样比较清晰,不然在后面使用settimeout可能会有些出乎意料的问题。

var temp = new Promise(function(resolve,reject) {
    console.log('第0层')
    resolve()
})
a = temp
.then(
    function() {//该函数被调用因为使用了resolve函数,promise对象是fulfilled
        console.log()
        console.log('第1层的resolved对应的函数')
        return new Promise(function(resolve,reject) {reject('')})
    },
    function() {//该函数不会被调用
        console.log()
        console.log('第1层的rejected对应的函数')
        return new Promise(function(resolve,reject) {resolve('')})        
    }
)
.then(
    function() {//该函数不会被调用
        console.log()
        console.log('第2层的resolved对应的函数')
        return new Promise(function(resolve,reject) {resolve('')})
    },  
    function() {//该函数会被调用
        console.log()
        console.log('第2层的rejected对应的函数')
        return new Promise(function(resolve,reject) {resolve('')})        
    }
)
//输出为:
//第0层
//第1层的resolved对应的函数
//第2层的rejected对应的函数

这里要注意第一个then调用的是resolve对应的函数,因为一开始的peomise对象被设置成fulfilled状态了。第二个then调用的是rejected对应的函数,因为再第一个then返回的peomise对象的状态是rejected的

catch()函数

在then()函数中可以省略rejected状态对应的函数,例如在then的链式调用中只要出现异常就推出。这个时候由catch来捕获rejected状态并且对其做出反应。

var temp = new Promise(function(resolve,reject) {
    console.log('第0层')
    resolve()
})
a = temp
.then(
    function() {
        console.log()
        console.log('第1层的resolved对应的函数')
        return new Promise(function(resolve,reject) {reject('')})
    },

)
.then(
    function() {
        console.log()
        console.log('第2层的resolved对应的函数')
        return new Promise(function(resolve,reject) {resolve('')})
    },  

)
.catch(function() {
    console.log("错误 我抓住你了")
})
//输出为:
//第0层
//第1层的resolved对应的函数
//错误 我抓住你了

这里第一个then返回的promise对象的状态是rejected的,应该调用第二个then对应的rejected状态对应的函数,可是第二个then没有rejected对应的函数,那么就会接着向下找,就找到了catch()。然后执行catch函数体。这也称为catch的穿透性。
接着我们看下面这串代码

var temp = new Promise(function(resolve,reject) {
    console.log('第0层')
    reject()
})
a = temp
.then(
    function() {
        console.log()
        console.log('第1层的resolved对应的函数')
        return new Promise(function(resolve,reject) {reject('')})
    },

)
.then(
    function() {
        console.log()
        console.log('第2层的resolved对应的函数')
        return new Promise(function(resolve,reject) {resolve('')})
    },  
    function() {
        console.log()
        console.log('第2层的rejected对应的函数')
        return new Promise(function(resolve,reject) {resolve('')})        
    }
)
.catch(function(params) {
    console.log("错误 我抓住你了")
})
//输出为:
//第0层
//第2层的rejected对应的函数

我们在第0层的时候就将promise对象的状态设置为rejected了,那么应该执行第一个then的rejected函数。可是第一个then没有,再找第二个then。第二个then有rejected对应的函数,就执行第二个rejected对应的函数,但是不执行catch。因为这个时候穿透不到catch

all()函数

列表中的所有promise对象都从pending转换成resolved后,all执行结束。第一个promise对象失败,返回这个失败的对象。

function resolveTest(content) {
    return new Promise(function (resolve, reject) {
        resolve(content)
    })
}

function rejectTest(content) {
    return new Promise(function (resolve, reject) {
        reject(content)
    })
}

var resolveTestPromise = Promise.all([resolveTest(1),resolveTest(2),resolveTest(3)])
var rejectTestPromise = Promise.all([resolveTest(1),rejectTest(2),rejectTest(3)])
console.log(resolveTestPromise)
//输出为:
//[[PromiseStatus]]: "fulfilled"
//[[PromiseValue]]: Array(3)
console.log(rejectTestPromise)
//输出为:
//[[PromiseStatus]]: "rejected"
//[[PromiseValue]]: 2

all方法适合使用在需要多个异步返回的结果的情况下

race()函数

哪个结果获得的快,就返回那个结果,不管结果本身是成功状态还是失败状态。

function resolveTest(content) {
    return new Promise(function (resolve, reject) {
        resolve(content)
    })
}

function rejectTest(content) {
    return new Promise(function (resolve, reject) {
        reject(content)
    })
}

var testPromise = Promise.all([rejectTest(1),resolveTest(2),resolveTest(3)])

console.log(testPromise)
//输出为:
//[[PromiseStatus]]: "rejected"
//[[PromiseValue]]: 1

Promise.reject()函数

返回一个带有拒绝原因的Promise对象。

var rejectPromise = Promise.reject("这是一个rejectd的promise对象")
console.log(rejectPromise)
//输出为:
//[[PromiseStatus]]: "rejected"
//[[PromiseValue]]: "这是一个rejectd的promise对象"

Promise.resolve()函数

用法1
返回一个带有拒绝原因的Promise对象。

var rejectPromise = Promise.reject("这是一个rejectd的promise对象")
console.log(rejectPromise)
//输出为:
//[[PromiseStatus]]: "rejected"
//[[PromiseValue]]: "这是一个resolve的promise对象"

用法2
传入一个带有then方法的对象,会立即执行这个方法。

var objwiththen = {
  then: function(resolve, reject) {
    resolve(42);
  }
};
var p1 = Promise.resolve(objwiththen);
console.log(p1)
//输出:
//[[PromiseStatus]]: "fulfilled"
//[[PromiseValue]]: 42
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值