嵌套的promise执行顺序以及多个promise顺序执行

1. promise.resolve()

① 不带参数的时候,直接返回一个resolved状态的promise对象

promiseStatus:resolved

promiseValued : undefined

② 带参数时 参数会传给回调函数

promiseStatus:resolved

promiseValued : 参数


2. 每次调用then都会返回一个新创建的promise对象

情况①若then方法中含有return语句,且返回的是一promise对象,则该对象作为then返回的新对象;

情况②若返回的是一个非promise对象,则返回的新promise对象的promiseValue为该值;

情况③若无返回值则返回的新promise对象promiseValue为undefined。

扫描二维码关注公众号,回复: 9680290 查看本文章
let newPromise = Promise.resolve().then(res =>{
    // 无返回值
})
let newPromise2 = Promise.resolve().then(() => {
    // 返回一个非promise对象
    return "hello" 
})
let newPromise3 = Promise.resolve().then(() => {
     // 返回promise对象
    return new Promise((resolve, reject) => {
        resolve("bonjour")
    })
})
console.log(newPromise, newPromise2, newPromise3)

3. 只有返回promsie对象后才会链式调用

Promise.resolve().then(res => { //then1
   console.log('1')
   new Promise((resolve, reject) => { 
        setTimeout(() => {
            console.log('2')
            resolve('newPromise')
        }, 2000);
    }).then(res =>{ // then2
        console.log('3')
        return "newPromise1"
        // 返回了一个非promsie对象,对应2中的情况2
    })
    // 无return语句,对应2中的情况3 
}).then(res=>{ // then3
    console.log('4', res)
})

 输出结果是:1 4 undefined  2 3

为什么then3先于then2执行?

捋下代码执行顺序便能理解:

执行then1, 输出1,执行同步任务new promise实例,遇到异步任务挂起,继续向下执行,then1中无return语句,则对应2中的情况①,返回一个值为undefined的promise对象,链式调用then3,输出 4 undefined ,2s后输出2,调用then方法输出3,且又创建了一个值为newPromise1的promise对象。

Promise.resolve().then(res => { //then1
   console.log('1')
    // then1中返回一个新的promise实例 只有当then1中返回的promise状态确定后才会进行下一步的链式调用 then3
   return new Promise((resolve, reject) => { 
        setTimeout(() => {
            console.log('2')
            resolve('newPromise')
        }, 2000);
    }).then(res =>{ // then2
        console.log('3')
        return "newPromise1"
    })
   // 有return语句,且返回了一个promise对象,对象2中的情况1
}).then(res=>{ // then3
    console.log('4', res)
})

输出结果: 1 2  3 4 newPromise1

多了一个return后执行顺序完全不同,呼应了第三条的标题:只有返回promsie对象后才会链式调用。

因为then1中含有return语句,且返回了一个promise对象,代码中先new一个promise实例,且由于每次调用then都会创建一个新的promise实例,所以只有当执行完 return "newPromsie1"后,then1返回一个值为newPromise1的promise对象,才会继续链式调用then3。

可以利用这种特性去实现顺序执行多个异步任务


4. 顺序执行多个异步任务

第一种思路是利用then链式调用的特点实现

1.直接then链式调用 不多说

2.利用Promise.resolve()+forEach循环/reduce循环,将promise串成一任务队列,本质上是简化的链式调用

三个模拟的异步任务

let a = function() {
    return new Promise((resolve, reject) => {
        setTimeout(()=>{
            console.log('11111111111',)
            resolve('第一个异步进程')
        },3000)
    })
} 
let b = function(){
    return new Promise((resolve, reject) => {
        setTimeout(()=>{
            console.log('2222222222' )
            resolve('第二个异步进程')
        },2000)
    })
}
let c = function(){
    return new Promise((resolve, reject) => {
        setTimeout(()=>{
            console.log('3333333333333')
            resolve('第三个异步进程')
        },1000)
    })
} 

reduce构建异步队列

let promiseArr = [a, b, c]
promiseArr.reduce((prev, cur)=>{
    return prev.then(() => {
            return cur().then(res => {
                console.log( res)
            })
    })
}, Promise.resolve())

本质上相当于

Promise.resolve().then(res => {
    return new Promise((resolve, reject) => {
        setTimeout(()=>{
            console.log('11111111111', )
            resolve('第一个异步进程')
        },3000)
    })
    // 只有当第一个then返回了promise对象才会接着调用下一个的then方法
}).then(() => {
    return new Promise((resolve, reject) => {
        setTimeout(()=>{
            console.log('2222222222', )
            resolve('第二个异步进程')
        },2000)
    })
}).then(() => {
    return new Promise((resolve, reject) => {
        setTimeout(()=>{
            console.log('33333333', )
            resolve('第三个异步进程')
        },1000)
    })
})

forEach构建异步队列

function fun(arr){
    let res = Promise.resolve()
    arr.forEach(item => {
        res = res.then(item)
    })
}
fun([a,b,c]).then( res => {
    console.log(res)
})

//相当于
Promise.resolve().then(
    a
).then(
    b
).then(
    c
)

3. async await实现

let arr = [a, b, c]
async function fun(arr){
    for(const item of arr){
        const res = await item().then()
        console.log(res)
    }
}
fun(arr)
发布了32 篇原创文章 · 获赞 1 · 访问量 2908

猜你喜欢

转载自blog.csdn.net/yyk5928/article/details/103624315