搜 索

Promise详解

  • 422阅读
  • 2022年05月27日
  • 3评论
首页 / JS高级 / 正文

未标题-1.jpg

Promise

Promise有三种状态,分别是:等待(pending)已完成(fulfilled)已拒绝(rejected)

Promise初始状态为:等待状态,可以通过他的两个参数 resolvereject 进行改变,前者为 成功状态、后者为 失败状态,两个参数名可以自定义,但不推荐。

语法

const p = new Promise(function(resolve,reject){
    // resolve('成功')
    // reject('失败')
})

需要注意的是:状态一旦确定,就无法再次进行改变,它不能够覆盖前面的状态

const p = new Promise(function(resolve,reject){
    resolve('成功') //成功状态
    reject('失败') //它不能够覆盖前面的状态
})

then / catch

成功状态则执行 then,用于接收成功状态的数据

const p = new Promise(function(resolve,reject){
    resolve('成功')
})

p.then(function(data){
    console.log(data); //成功
})

失败状态则执行 catch,用于接收失败状态的数据

const p = new Promise(function(resolve,reject){
    reject('失败')
})

p.catch(function(data){
    console.log(data); //失败
})

为什么需要用Promise?

看以下应用场景:一秒钟后输出111,两秒222,三秒333

setTimeout(function(){
    console.log(111);

    setTimeout(function(){
        console.log(222);

        setTimeout(function(){
            console.log(333);
        },1000)
    },1000)
},1000)

虽然效果也能实现,但是需要层层回调。严重影响代码可读性。专业术语叫做:回调地狱

所以就可以使用 Promise 解决回调地狱这个问题

// data->数据   time->时间
function time(data,time) {
    return new Promise((resolve, reject) => {
        setTimeout(()=>{
            resolve(data)
        },time)
    })
}

const p1 = time(111,1000);
const p2 = time(222,1000);
const p3 = time(333,1000);

p1.then((data)=>{
    console.log(data)

    return p2
}).then((data)=>{
    console.log(data)

    return p3
}).then((data)=>{
    console.log(data)
})

async / await

用法

async / await 同步的方式编写异步的代码:等p1输出成功后输出p2,p2输出成功后输出p3

// data->数据   time->时间
function time(data,time) {
    return new Promise((resolve, reject) => {
        setTimeout(()=>{
            resolve(data)
        },time)
    })
}

// 用同步的方式编写异步的代码
async function fun(){
    const p1 = await time(111,1000);
    console.log(p1)
    const p2 = await time(222,1000);
    console.log(p2)
    const p3 = await time(333,1000);
    console.log(p3)
}
fun()

扩展

你不知道的 Promise

then 不仅可以接收成功状态的数据,也可以接收失败状态的数据。

then 也可以写两个参数,参数一:用于 接收成功状态、参数二:用于 接收失败状态

const p = new Promise((resolve, reject) => {
    reject('失败')
})

p.then(
    function (data) { //参数一:接收成功状态数据
        console.log(data);
    }, function (data) { //参数二:接收失败状态数据
        console.log(data); //失败
    }
)

那么看下面这个案例

const p = new Promise((resolve, reject) => {
    reject('失败')
})

p.then(
    function (data) {
        console.log(data);
    }, function (data) {
        console.log(data); //失败
    }
).then(
    function(){
        console.log(111); //111
    },function(){
        console.log(222);
    }
)

答案输出的是:失败111,第一个then中就不必多解释,输出失败,第二个then输出111。具体看如下解释:

const p = new Promise((resolve, reject) => {
    reject('失败')
})

p.then(
    function (data) {
        console.log(data);
    }, function (data) {
        console.log(data); //失败
        // 这里需要写返回值,如果不写,则默认return返回undefined,并且返回成功状态。
    }
).then(
    //默认会返回一个成功状态,所以自然也就执行第一个参数的function函数
    function(data){
        console.log(data); //默认没有写返回值,返回:undefined
    },function(data){
        console.log(data);
    }
)

再往下看

const p = new Promise((resolve, reject) => {
    reject('失败')
})

p.then(
    function (data) {
        console.log(data);
    }, function (data) {
        console.log(data); //失败
        // 有参数则返回
        return 123;
    }
).then(
    // 默认是成功状态
    function(data){
        console.log(data); //返回:123
    },function(data){
        console.log(data);
    }
)

如果想让第二个then执行失败状态,需要给return手动返回失败状态

const p = new Promise((resolve, reject) => {
    reject('失败')
})

p.then(
    function (data) {
        console.log(data);
    }, function (data) {
        console.log(data); //失败
        // 手动返回为失败状态
        return new Promise((resolve, reject) => {
            reject(222)
        })
    }
).then(
    function(data){
        console.log(data);
    },function(data){
        console.log(data); //返回:222
    }
)

结果就是:失败 、 222

评论区
Nefelibata 2022年5月27日 16:39
回复

我是最佳助手

梦想家阳阳 梦想家阳阳
2 条回复
梦想家阳阳
梦想家阳阳 2022年5月27日 17:24
回复

梦想家阳阳
梦想家阳阳 2022年5月27日 17:24
回复

avatar