oliver1204 / randomNotes

用来记录平时的日常总结
1 stars 0 forks source link

你不知道的Promise以及JS的事件循环 #84

Closed oliver1204 closed 5 years ago

oliver1204 commented 5 years ago

1.题目一

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 有 3 种状态:pending、fulfilled 或 rejected。状态改变只能是 pending->fulfilled 或者 pending->rejected,状态一旦改变则不能再变。

结论:promise 状态一旦改变则不能再变。

2.题目二

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 1005
success 1007

解释:

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

3.题目三

const promise = Promise.resolve()
  .then(() => {
    return promise
  })
promise.catch(console.error)

运行结果:

TypeError: Chaining cycle detected for promise #<Promise>
    at <anonymous>
    at process._tickCallback (internal/process/next_tick.js:188:7)
    at Function.Module.runMain (module.js:667:11)
    at startup (bootstrap_node.js:187:16)
    at bootstrap_node.js:607:3

解释:

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

4.题目四

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

运行结果:

1

解释:

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

5.题目五

new Promise((resolve, reject) => {
    setTimeout(() => { console.log('1');   }, 3000)
    resolve(1);
})
.then(() => {
    Promise.resolve().then(() => { 
        Promise.resolve().then(()=> {console.log('2')})
    })
})
.then(() => {
 console.log('3')
})

运行结果:

321

6.题目六

new Promise((resolve, reject) => {
    setTimeout(() => { console.log('1'); }, 3000)
    resolve(1);
})
.then(() => {   
    Promise.resolve().then(() => { console.log('2') })
})
.then(() => {
    console.log('3')
})

运行结果:

231

7.题目七

new Promise((resolve, reject) => {
    setTimeout(() => { console.log('1'); }, 3000)
    resolve(1);
})
.then(() => {
    Promise.resolve().then(() => { 
        Promise.resolve().then(() => { console.log('4') }) 

        Promise.resolve().then(() => { 
            Promise.resolve().then(()=> {console.log('2')})
        })
    })
})
.then(() => {
    Promise.resolve().then(() => { console.log('1') })
    console.log('3')
})

运行结果:

3412

题目做完了,先看一篇文章:

从一道题浅说 JavaScript 的事件循环

文章重点提炼:

Promise.resolve 方法允许调用时不带参数,直接返回一个resolved 状态的 Promise 对象。立即 resolved 的 Promise 对象,是在本轮“事件循环”(event loop)的结束时,而不是在下一轮“事件循环”的开始时。