慢慢深入promise

177 阅读4分钟


本文已参与「新人创作礼」活动,一起开启掘金创作之路。

promise

同步代码和异步代码

谈promise之前我们得先了解一下什么是同步代码和异步代码。
同步代码:执行完前一行再执行后一行。代码的执行顺序是跟排列顺序一样的。简单来说就是执行实现非常快,几乎可以忽略不计的代码,比如console.log() 异步代码:当执行一段代码时要话费一点时间,js就会先去执行其他代码。简单来说,执行要花费一定时间的代码就是异步代码,比如定时器,接口请求

primose的作用

咱们先来看一段代码

function fun1() {
    setTimeout(() => {
        console.log("我先执行");
    }, 1000)
}

function fun2() {
    console.log("我后执行");
}
fun1()
fun2()
//执行结果: 我后执行 我先执行

定时器会花费较长时间是一段异步代码,所以会先执行fun2()再执行fun1() 但是我们的需求就是想要先执行fun1()再执行fun2()怎么办呢?函数回调是一个办法!

函数回调解决异步代码

function fun1() {
    setTimeout(() => {
        console.log("我先执行");
        fun2()
    }, 1000)
    
}

function fun2() {
    console.log("我后执行");
}
fun1()

//执行结果:我先执行 我后执行

这也算一个解决办法,但是异步代码多了想要按规定顺序执行呢?那就会一个函数套另一个函数会一直套下去,这样就会产生一个回调地狱!一个函数编译完就会放到执行栈中执行,函数还没结束又放入函数内部的另一个函数,这样下去栈就会爆满。那么有没有更加优雅的解决方式呢?有!

primose解决异步代码

function fun1() {
    return new Promise((resolve) => {
        setTimeout(() => {
            console.log("我先执行");
            resolve('ok')
        }, 1000)

    })
}

function fun2() {
    console.log("我后执行");
}
fun1().then(()=>{
})
//执行结果:我先执行 我后执行

这样就实现了,让函数先后执行,并且不会产生回调地狱,那么有了前面的铺垫咱们就可以深入primose啦!!

promise简单介绍

promise

promise是一个构造函数对象,用来生成一个promise对象,参数是一个函数(想要先执行的函数),函数有两个参数 resolve和reject;

let promise=new Promise((resolve, reject) => {
    
})

这个promise对象有一个then()方法,参数也是一个函数(想要后执行的函数),返回值是一个新的promise! then()方法执行或者不执行全看promise对象的状态

promise的状态

Promise有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。Promise 对象的状态改变,只有两种可能:从 pending 变为 fulfilled 和从 pending 变为 rejected 。他的这种状态全由promise里面函数的执行的resolve()方法和reject()来控制! 刚开始promise状态为pending,不会执行then()方法

let promise = new Promise((resolve, reject) => {
    console.log(1);
    console.log(2);
})
promise.then(() => {
    console.log(3);
})
//1 2

当promise里面的函数调用resolve(),promise对象从pending状态变为fulfilled,才会执行then()方法!!

let promise = new Promise((resolve, reject) => {
    console.log(1);
    console.log(2);
    resolve()
})
promise.then(() => {
    console.log(3);
})

那么reject呢??

let promise = new Promise((resolve, reject) => {
    console.log(1);
    console.log(2);
    reject()
})
promise.then(() => {
    console.log(3);
})
// node:internal/process/promises:279
//             triggerUncaughtException(err, true /* fromPromise */);
//             ^

// [UnhandledPromiseRejection: This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). The promise rejected with the reason "undefined".] {
//   code: 'ERR_UNHANDLED_REJECTION'
// }

会报错,因为当promise里面的函数调用resolve(),promise对象从pending状态变为rejected,不会执行then()方法,而是执行catch()方法!

let promise = new Promise((resolve, reject) => {
    console.log(1);
    console.log(2);
    reject()
})
promise.catch(() => {
    console.log(3);
})
//1 2 3 

那如果都有呢??

let promise = new Promise((resolve, reject) => {
    console.log(1);
    console.log(2);
    reject()
})
promise.then(() => {
    console.log(4);

}).catch(() => {
    console.log(3);
})
//1 2 3
let promise = new Promise((resolve, reject) => {
    console.log(1);
    console.log(2);
    resolve()
})
promise.then(() => {
    console.log(4);

}).catch(() => {
    console.log(3);
})
//1 2 4

不对应不会执行但是也不会报错。 还有一个finally函数,不论是promise内部函数调用resolve函数或者或者reject函数它都会执行!

let promise = new Promise((resolve, reject) => {
    console.log(1);
    console.log(2);
    resolve()
})
promise.then(() => {
    console.log(4);

}).finally(() => {
    console.log(5);
})
//1 2 4 5
let promise = new Promise((resolve, reject) => {
    console.log(1);
    console.log(2);
    reject()
})
promise.catch(() => {
    console.log(4);

}).finally(() => {
    console.log(5);
})
//1 2 4 5

但是reject或者resolve一定要有其一或者全有,不然不会执行!

let promise = new Promise((resolve, reject) => {
    console.log(1);
    console.log(2);

})
promise.finally(() => {
    console.log(5);
})
//1 2

一旦状态改变,就不会再变,会一直保持这个结果。 resolve()和reject()里面的参数可以分别传递给then()和catch()

let promise = new Promise((resolve, reject) => {
    console.log(1);
    console.log(2);
    resolve(3)
})
promise.then((res) => {
    console.log(res);
})
//1 2 3
let promise = new Promise((resolve, reject) => {
    console.log(1);
    console.log(2);
    reject(3)
})
promise.catch((res) => {
    console.log(res);
})
//1 2 3