Promise用法

120 阅读4分钟

Promise的作用:一种处理异步代码的方式,避免回调地狱。

1.创建Promise对象:

const promise = new Promise((resovle, reject) => {
    // console.log('执行传入的函数')  
})

2.resolve详解

给resolve传入不同的值

(1)普通的值或者对象:当前promise的状态变为fullfiled

(2)传入一个promise :当前promise的状态由传入的promise状态决定,而且,传递的值也由传入的promise来决定

const p1 = new Promise((resolve, reject) => {
    resolve('p1-resolve')
})
new Promise((resolve, reject) => {
    console.log('---------')
    resolve(p1)
    // reject()
}).then((res) => {
    console.log("res", res)
}, (err) => {
    console.log("err", err)
})

(3)传入一个对象,并且这个对象实现了then方法,那么这个then方法会被执行,且该then方法决定当前promise的状态及传出的值

const obj = {
    name:'zhangsan',
    then: function() {
        console.log('对象实现then方法')
        // resolve('对象实现then方法resolve')
        // reject('对象实现then方法reject')
    }
}
new Promise((resolve, reject) => {
    resolve(obj)
}).then((res) => {
    console.log('promise-resolve', res)
}, (err) => {
    console.log('promise-reject', err)
}).finally(() => {
    console.log('promise-finally')
})

3.Promise对象方法

1.同一个promise多次调用then方法,所有的传入then的回调函数都会被执行

const promi1 = new Promise((resolve, reject) => {
    resolve('promi1-Resolve')
})

promi1.then((res) => {
    console.log('res1',res)
})
promi1.then((res) => {
    console.log('res2',res)
})
promi1.then((res) => {
    console.log('res3',res)
})
// 结果:
// res1 promi1-Resolve
// res2 promi1-Resolve
// res3 promi1-Resolve

2.给then方法传入的函数可以有返回值

(1)返回一个普通值,那么这个值将会被当作一个新的promiseresolve

new Promise((resolve, reject) => {
    resolve()
}).then((res) => {
    // return {name: 'zhangsan'}
    return '哈哈哈哈哈哈'
}).then(res => {
    console.log('2--then',res)
})
// 2--then 哈哈哈哈哈哈

(2)返回一个promise,则将这个新的promise作为then中返回的promiserosolve的值

new Promise((resolve, reject) => {
    resolve('222')
    // reject('333')
}).then((res) => {
    console.log(res)
    return new Promise((resolve, reject) => {
        // resolve('返回一个promise')
        reject('返回一个promise')
    })
}).then(res => {
    console.log('resolve', res)
}).catch((err) => {
    console.log('catch',err)
})
// 结果:
// 222
// catch 返回一个promise

(3)返回一个对象,且这个对象实现了then方法,那么then()新建的promise的状态及传出的值由对象实现的then方法来决定

new Promise((resolve, reject) => {
    resolve('333')
}).then((res) => {
    console.log(res)
    return {
        then: function(resolve, reject) {
            // resolve('实现了then方法的对象')
            reject('实现了then方法的对象')
        }
    }
}).then((res) => {
    console.log('res',res)
}).catch((err) => {
    console.log('catch', err)
})
// 结果:
// 333
// catch 实现了then方法的对象

总结:无论resolve什么值,或是then中的回调函数返回值是什么,then()都会新建一个promise对象,并将then中回调函数的返回值作为新promiseresolve/reject的参数.

3.catch的返回值

catch的返回值是一个fullfilled状态的promise

const promise1 = new Promise((resolve, reject) => {
    reject('reject1')
}).then(res => {
    console.log('then-1',res)
}).catch( err => {
    console.log('catch-1',err)
}).then(res => {
    console.log('then-2',res)
}).catch(err => {
    console.log('catch-2', err)
})
// 结果:
// catch-1 reject1
// then-2 undefined

4.finally

finally最终一定会执行,但是不能用来接收reject的信息或者resovle的信息

const promise1 = new Promise((resolve, reject) => {
    resolve(123)
}).then(res => {
    console.log(res)
    return Promise.reject(456)
}).catch(err => {
    console.log(err)
}).finally((res) => {
    console.log('finally',res)
})
// 结果:
// 123
// 456
// finally undefined

5.all()

等所有的promiseresolve()之后再拿到结果,输出结果的顺序与all中数组元素的顺序相同

如果在所有promiseresolve之前,有一个promisereject(),则按照reject()的结果执行

注意:Promise.all()后面的then/catch中的回调函数不一定会等all中的promise状态全部变化后才执行(有reject就会立即往后执行)。

all中的某个promise状态变为reject或者all中的promise全变为fulfilled时,其后的then/catch就会立即执行

const p1 = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve('p1')
        // reject('p1')
    }, 1000);
})
const p2 = new Promise((resolve, reject) => {
    resolve('p2')
    // reject('p2')
    
})
const p3 = new Promise((resolve, reject) => {
    resolve('p3')
    // reject('p3')
})
const p4 = 123

Promise.all([p1, p2,p3, p4]).then(res => {
    console.log('res', res, p1)
}).catch(err => {
    console.log('err', err, p1)
    setTimeout(() => {
        console.log(p1)
    }, 0);
})
// 结果:
// res ['p1', 'p2', 'p3', 123] Promise {<fulfilled>: 'p1'}

6.allSettled()

等所有的promise都变化之后,再将所有结果放入一个数组,若有promise的状态没有变化,则不进行后续操作。

但是,保存结果的数组中存放的元素是对象,会标志对应的promisefulfilled还是rejected

const p1 = new Promise((resolve, reject) => {
    setTimeout(() => {
        // resolve('p1')
        reject('p1')
    }, 1000);
})
const p2 = new Promise((resolve, reject) => {
    reject('p2')
    // resolve('p2')
})
const p3 = new Promise((resolve, reject) => {
    // resolve('p3')
    reject('p3')
})
const p4 = 123

Promise.allSettled([p1, p2, p3, p4]).then(res => {
    console.log('res',res)
}).catch(err => {
    console.log('err',err)
})

结果:

image.png

7.race()

只要有一个promise的状态改变,那么就以这个promise的状态来执行后续代码(但是其他未执行完的promise仍然会执行完)

注意,race中数组元素的顺序会影响最终的结果

数组中放在前面的promise会先被执行

const p1 = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve('p1')
    }, 1000);
})
const p2 = new Promise((resolve, reject) => {
    // reject('p2')
    resolve('p2')
})
const p3 = new Promise((resolve, reject) => {
    // resolve('p3')
    reject('p3')
})


Promise.race([p1, p2,p3]).then(res => {
    console.log(res)
}).catch(err => {
    console.log(err)
})
// 结果:
// p2

8.any()

一直等到有resolvepromise产生之后,再执行resolve之后的操作

如果所有的promise都是rejected,那么会传递出一个错误对象

const p1 = new Promise((resolve, reject) => {
    setTimeout(() => {
        // resolve('p1')
        reject('p1')
    }, 1000);
})
const p2 = new Promise((resolve, reject) => {
    // resolve('p2')
    reject('p2')
})
const p3 = new Promise((resolve, reject) => {
    // resolve('p3')
    reject('p3')
})

Promise.any([p1, p2,p3]).then(res => {
    console.log(res)
}).catch(err => {
    console.log(err, err.errors)
})

结果:

image.png

const p1 = new Promise((resolve, reject) => {
    setTimeout(() => {
        // resolve('p1')
        reject('p1')
    }, 1000);
})
const p2 = new Promise((resolve, reject) => {
    resolve('p2')
    // reject('p2')
})
const p3 = new Promise((resolve, reject) => {
    // resolve('p3')
    reject('p3')
})

Promise.any([p1, p2,p3]).then(res => {
    console.log(res)
}).catch(err => {
    console.log(err, err.errors)
})
// 结果:
// p2