<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          【面試】1069- 前端必知必會(huì)的 10 道 Promise 面試題

          共 7336字,需瀏覽 15分鐘

           ·

          2021-09-03 13:24


          作者:HuberTRoy

          https://juejin.cn/post/6966857691381645325

          Promise 想必大家都十分熟悉,想想就那么幾個(gè) api,可是你真的了解 Promise 嗎?本文根據(jù) Promise 的一些知識(shí)點(diǎn)總結(jié)了十道題,看看你能做對(duì)幾道。

          以下 promise 均指代 Promise 實(shí)例,環(huán)境是 Node.js。

          題目一

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

          運(yùn)行結(jié)果:

          1
          2
          4
          3

          解釋:Promise 構(gòu)造函數(shù)是同步執(zhí)行的,promise.then 中的函數(shù)是異步執(zhí)行的。

          題目二

          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('promise1', promise1)
            console.log('promise2', promise2)
          }, 2000)

          運(yùn)行結(jié)果:

          promise1 Promise { <pending> }
          promise2 Promise { <pending> }
          (node:50928) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): Error: error!!!
          (node:50928) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
          promise1 Promise { 'success' }
          promise2 Promise {
            <rejected> Error: error!!!
              at promise.then (...)
              at <anonymous> }

          解釋:promise 有 3 種狀態(tài):pending、fulfilled 或 rejected。狀態(tài)改變只能是 pending->fulfilled 或者 pending->rejected,狀態(tài)一旦改變則不能再變。上面 promise2 并不是 promise1,而是返回的一個(gè)新的 Promise 實(shí)例。

          題目三

          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)
            })

          運(yùn)行結(jié)果:

          then: success1

          解釋:構(gòu)造函數(shù)中的 resolve 或 reject 只有第一次執(zhí)行有效,多次調(diào)用沒(méi)有任何作用,呼應(yīng)代碼二結(jié)論:promise 狀態(tài)一旦改變則不能再變。

          題目四

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

          運(yùn)行結(jié)果:

          1
          2

          解釋:promise 可以鏈?zhǔn)秸{(diào)用。提起鏈?zhǔn)秸{(diào)用我們通常會(huì)想到通過(guò) return this 實(shí)現(xiàn),不過(guò) Promise 并不是這樣實(shí)現(xiàn)的。promise 每次調(diào)用 .then 或者 .catch 都會(huì)返回一個(gè)新的 promise,從而實(shí)現(xiàn)了鏈?zhǔn)秸{(diào)用。

          題目五

          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)
          })

          運(yùn)行結(jié)果:

          once
          success 1005
          success 1007

          解釋:promise 的 .then 或者 .catch 可以被調(diào)用多次,但這里 Promise 構(gòu)造函數(shù)只執(zhí)行一次。或者說(shuō) promise 內(nèi)部狀態(tài)一經(jīng)改變,并且有了一個(gè)值,那么后續(xù)每次調(diào)用 .then 或者 .catch 都會(huì)直接拿到該值。

          題目六

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

          運(yùn)行結(jié)果:

          then: Error: error!!!
              at Promise.resolve.then (...)
              at ...

          解釋:.then 或者 .catch 中 return 一個(gè) error 對(duì)象并不會(huì)拋出錯(cuò)誤,所以不會(huì)被后續(xù)的 .catch 捕獲,需要改成其中一種:

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

          因?yàn)榉祷厝我庖粋€(gè)非 promise 的值都會(huì)被包裹成 promise 對(duì)象,即 return new Error('error!!!') 等價(jià)于 return Promise.resolve(new Error('error!!!'))

          題目七

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

          運(yùn)行結(jié)果:

          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 本身,否則會(huì)造成死循環(huán)。類似于:

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

          題目八

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

          運(yùn)行結(jié)果:

          1

          解釋:.then 或者 .catch 的參數(shù)期望是函數(shù),傳入非函數(shù)則會(huì)發(fā)生值穿透。

          題目九

          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)
            })

          運(yùn)行結(jié)果:

          fail2: Error: error
              at success (...)
              at ...

          解釋:.then 可以接收兩個(gè)參數(shù),第一個(gè)是處理成功的函數(shù),第二個(gè)是處理錯(cuò)誤的函數(shù)。.catch 是 .then 第二個(gè)參數(shù)的簡(jiǎn)便寫法,但是它們用法上有一點(diǎn)需要注意:.then 的第二個(gè)處理錯(cuò)誤的函數(shù)捕獲不了第一個(gè)處理成功的函數(shù)拋出的錯(cuò)誤,而后續(xù)的 .catch 可以捕獲之前的錯(cuò)誤。當(dāng)然以下代碼也可以:

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

          題目十

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

          運(yùn)行結(jié)果:

          end
          nextTick
          then
          setImmediate

          解釋:process.nextTick 和 promise.then 都屬于 microtask,而 setImmediate 屬于 macrotask,在事件循環(huán)的 check 階段執(zhí)行。事件循環(huán)的每個(gè)階段(macrotask)之間都會(huì)執(zhí)行 microtask,事件循環(huán)的開(kāi)始會(huì)先執(zhí)行一次 microtask。


          》聲明:文章著作權(quán)歸作者所有,如有侵權(quán),請(qǐng)聯(lián)系小編刪除。


          瀏覽 25
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  精品免费| 婷婷激情五月综合 | 三级在线观看 | 中国免费无码 | 在线视频日韩 |