[js] 你可能不会promise

1

Promise 构造函数与 console.log() 在stack里,按顺序执行。
promise.then 是microtask,在queue里,stack执行完后才会执行它。

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

        //1
        //2
        //4
        //3

2

Promise 构造函数与 console.log() 在stack里,按顺序执行。
promise.then 是 microtask,在 queue 里,stack执行完后才会执行它。
setTimeout 是 macrotask 也在 queue 里,microtask执行完后才会执行它。

        const promise1 = new Promise((resolve, reject) => {
            setTimeout(() => {
                resolve('success')
            }, 1000)
        })
        const promise2 = promise1.then(() => {
            throw new Error('error!!!')
        })

        console.log('promise1', promise1)
        console.log('promise2', promise2)

        setTimeout(() => {
            console.log('promise11', promise1)
            console.log('promise22', promise2)
        }, 2000)

//promise1 Promise {[[PromiseStatus]]: "pending", [[PromiseValue]]: undefined}
//promise2 Promise {[[PromiseStatus]]: "pending", [[PromiseValue]]: undefined}
//Uncaught (in promise) Error: error!!!
//promise11 Promise {[[PromiseStatus]]: "resolved", [[PromiseValue]]: "success"}
//promise22 Promise {[[PromiseStatus]]: "rejected", [[PromiseValue]]: Error: error!!!

promise 有 3 种状态:pending、fulfilled 或 rejected。状态改变只能是 pending->resolved 或者 pending->rejected,状态一旦改变则不能再变。
每次then之后都返回的是一个基于前一个promise对象的新promise对象。
上面 promise2 并不是 promise1,而是返回的一个新的 Promise 实例。

3

        const promise = new Promise((resolve, reject) => {
            resolve('success1')
            reject('error')
            resolve('success2')
        })

        promise
            .then((res) => {
                console.log('then: ', res)
            })
            .catch((err) => {
                console.log('catch: ', err)
            })

        //then:  success1

构造函数中的 resolve 或 reject 只有第一次执行有效,多次调用没有任何作用,promise 状态一旦改变则不能再变。

4

        Promise.resolve(1)
            .then((res) => {
                console.log(res)
                return 2
            })
            .catch((err) => {
                return 3
            })
            .then((res) => {
                console.log(res)
            })

            //1 
            //2

promise 可以链式调用。提起链式调用我们通常会想到通过 return this 实现,不过 Promise 并不是这样实现的。promise 每次调用 .then 或者 .catch 都会返回一个新的 promise,从而实现了链式调用。

5

const start = Date.now()在 和 promise构造函数在stack里;
虽然promise.then是microtask,setTimeout是macrotask,但是promise.then只有resolve或reject了才会触发(才会进入queue)。

        const promise = new Promise((resolve, reject) => {
            setTimeout(() => {
                console.log('once')
                resolve('success')
            }, 1000)
        })

        const start = Date.now();
        promise.then((res) => {
            console.log(res, Date.now() - start)
        })
        promise.then((res) => {
            console.log(res, Date.now() - start)
        })

        //once 
        //success 1001 
        //success 1002

promise 的 .then 或者 .catch 可以被调用多次,但这里 Promise 构造函数只执行一次。或者说 promise 内部状态一经改变,并且有了一个值,那么后续每次调用 .then 或者 .catch 都会直接拿到该值。

6

        Promise.resolve()
            .then(() => {
                return new Error('error!!!')
            })
            .then((res) => {
                console.log('then: ', res)
            })
            .catch((err) => {
                console.log('catch: ', err)
            })

            //then:  Error: error!!!

.then 或者 .catch 中 return 一个 error 对象并不会抛出错误,所以不会被后续的 .catch 捕获,因为返回任意一个非 promise 的值都会被包裹成 promise 对象,即
return new Error('error!!!')
等价于
return Promise.resolve(new Error('error!!!'))

需要改成其中一种:

return Promise.reject(new Error('error!!!'))

throw new Error('error!!!')

7

        const promise = Promise.resolve()
            .then(() => {
                return promise
            })
        promise.catch(console.error)
        
        //TypeError: Chaining cycle detected for promise #<Promise>

.then 或 .catch 返回的值不能是 promise 本身,否则会造成死循环。类似于:

process.nextTick(function tick () {
  console.log('tick')
  process.nextTick(tick)
})

8

        Promise.resolve(1)
            .then(2)
            .then(Promise.resolve(3))
            .then(console.log)

        //1

.then 或者 .catch 的参数期望是函数,传入非函数则会发生值穿透。

9

        Promise.resolve()
            .then(function success(res) {
                throw new Error('error')
            }, function fail1(e) {
                console.error('fail1: ', e)
            })
            .catch(function fail2(e) {
                console.error('fail2: ', e)
            })

            //fail2:  Error: error

.then 可以接收两个参数,第一个是处理成功的函数,第二个是处理错误的函数。.catch 是 .then 第二个参数的简便写法,但是它们用法上有一点需要注意:.then 的第二个处理错误的函数捕获不了第一个处理成功的函数抛出的错误,而后续的 .catch 可以捕获之前的错误。
当然以下代码也可以:

        Promise.resolve()
            .then(function success1(res) {
                throw new Error('error')
            }, function fail1(e) {
                console.error('fail1: ', e)
            })
            .then(function success2(res) {
                console.log('success2: ', res)
            }, function fail2(e) {
                console.error('fail2: ', e)
            })

            //fail2:  Error: error

10

console.log 属于 stack。
process.nextTick 和 promise.then 属于 microtask,
setImmediate 属于 macrotask。

process.nextTick(() => {
    console.log('nextTick')
})
Promise.resolve()
    .then(() => {
        console.log('then')
    })
setImmediate(() => {
    console.log('setImmediate')
})
console.log('end')

//end
//nextTick
//then
//setImmediate

11

        new Promise(resolve => {
            resolve(new Promise(reject => {
                setTimeout(() => {
                    reject(Promise.resolve(1))
                }, 3000)
            }))
        })
            .then(console.log)
            .catch(console.error)

        //1

resolve一个promise实例时,这个resolve的promise会继续执行下去,直到resolve的不是promise,then才会执行.

转载于:https://www.cnblogs.com/qingmingsang/articles/7827967.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值