浅说Promise、async和await

Promise基本概念

promise是一个对象,他的定义格式是这样的

new Promise((resolve, reject) => {
        
})
//后面可以接then或catch

promise有三个状态:{

1、pending-----[待定]初始状态

2、fulfilled----- [实现]操作成功

3、rejected -------[被否决]操作失败

}

resolvereject分别是用来标记promise实现否决状态的两个参数

当promise状态发生改变,就会触发then()或catch()的响应函数处理后续步骤,如果标记为resolve,则触发then(),反之则为catch()

promise状态一经改变,不会再变。

Promise对象的状态改变,只有两种可能:

从pending变为fulfilled

从pending变为rejected。

这两种情况只要发生,状态就凝固了,不会再变了。

实践是检验真理的唯一标准

demo

demo()
function demo() {
    new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve('已过两秒')
        }, 2000);
    }).then(res => {
        console.log('res: ', res)
    })
}

运行结果:两秒后输出res

这说明then方法可以获取到resolve()标记的内容并且使用

换成reject试试:

demo()
function demo() {
    new Promise((resolve, reject) => {
        setTimeout(() => {
            reject('已过两秒')
        }, 2000);
    }).then(res => {
        console.log('res: ', res)
    }).catch(err => {
        console.log('err: ', err)
    })
}

可以看到,then中的语句没有执行,而是直接跳到了catch

demo2

demo2()
function demo2() {
    new Promise((resolve, reject) => {
        resolve('标记为resolve')
        reject('标记为reject')
        console.log('如果输出这一句话,说明resolve和reject后的语句还可以执行')
    }).then(res => {
        console.log('第一次then: ', res)
        return '第一次then的return值'
    }).then(res => {
        console.log('第二次then:', res)
    }).catch(err => {
        console.log('catch: ', err)
    })
}

运行结果:

结果说明了三件事:

  1. resolve和reject只是标记promise的状态,并不会直接开始执行then或者catch里的语句

  1. promise状态被标记后就不会更改,因为catch并没有执行

  1. then()中return的值可以被下一次then()调用

async和await的基本概念

async是asynchronous(翻译结果为:异步的) 的缩写

await是async wait的缩写,也就是 异步等待

async是函数的声明,用于声明函数是异步函数,并不是说想要把一个函数变为异步的就一定需要async

这个声明只是为了await的使用

await 用于等待一个表达式或函数的执行完成,在完成前不允许执行之后的语句,并且只能在有async声明的函数中使用

也就是说如果一个函数声明了async,但是没有在这个函数中使用await,则这个声明没有意义,原来是怎么样就还是怎么样

实践

demo3

testDemo3()

function demo3() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve('ok')
            console.log('三秒已过')
        }, 3000);
    })
}

async function testDemo3() {
    console.log(demo3())
    console.log(await demo3())
    console.log('看看这一句话出来要多久:')
}

运行结果

运行后马上输出:

三秒后继续输出:

来分析一下:

  1. 开始执行第一次log时,由于没有用await标记,是立刻输出demo3()的,并且开始执行demo3()里面的语句,而demo3() return了一个promise对象,所以会输出Promise{ <pending> },pending表示这一时刻的promise对象还是初始状态,三秒后,demo3()执行完成,输出‘三秒已过’(先输出再执行,执行用了三秒)

  1. 第二次log是紧接着第一次log的,并且用await标记了demo3(),所以当demo3()执行完成时,也就是3秒后,才执行log。(没等第一次demo3执行完就开始了,并且第二次demo3与第一次间隔甚短)所以两个‘三秒已过’几乎是同时出现。然后还发现用await标记了的demo3会返回他的resolve值

  1. 第三次log也是三秒后出来的,这说明他被第二次log中的await阻塞了

将testDemo3改一改,demo3原封不动:

testDemo3()

function demo3() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve('ok')
            console.log('三秒已过')
        }, 3000);
    })
}

async function testDemo3() {
    let x = await demo3()
    console.log('x: ', x)
}

运行结果

demo4

demo4()

async function demo4() {
    let pro = new Promise(resolve => {
        setTimeout(() => {
            console.log('五秒已过')
            resolve('ok')
        }, 5000);
    })
    console.log('pro: ', pro)
    await pro
    console.log('pro: ', pro)
}

运行结果

猜你喜欢

转载自blog.csdn.net/Ice1774/article/details/129114918