Promise的10大知識點!

通知:假期延長到2月2號。
通知:假期延長到2月10號。
通知:假期延長到2月17號。
通知:公司沒有了,不要回來了。

下面是今天的前端知識

Part 1:

const prom = new Promise((res, rej) => {
  console.log('first');
  res();
  console.log('second');
});
prom.then(() => {
  console.log('third');
});
console.log('fourth');


// first
// second
// fourth
// third

知識點:Promise 構造函數是同步執行,promise.then 是異步執行。

Part 2:

const prom = new Promise((res, rej) => {
  setTimeout(() => {
    res('success');
  }, 1000);
});
const prom2 = prom.then(() => {
  throw new Error('error');
});


console.log('prom', prom);
console.log('prom2', prom2);


setTimeout(() => {
  console.log('prom', prom);
  console.log('prom2', prom2);
}, 2000);


// prom Promise {<pending>}
// prom2 Promise {<pending>}
// Promise {<resolved>: "success"}
// prom2 Promise {<rejected>: Error: error }

知識點:promise 有三種不同的狀態:pending、fulfilled、rejected,一旦狀態更新,就不再改變,只能從pending->fulfilled 或 pending->rejected 。

Part 3:

const prom = new Promise((res, rej) => {
  res('1');
  rej('error');
  res('2');
});


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


// then: 1

知識點:一旦 resolve 和 reject 同時存在,只會執行第一個,後面的不再執行。

Part 4:

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


// 1
// 2

知識點:每次 promise 調用 .then 或 catch 時,都會返回一個新的 promise,從而實現鏈接調用。

Part 4:

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


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


// first
// second 1054 third
// second 1054 fourth

知識點:一個 promise .then 或 .catch 可以被多次調用,但是此處Promise構造函數僅執行一次。 換句話說,一旦promise 的內部狀態發生變化並獲得了一個值,則隨後對 .then 或 .catch 的每次調用都將直接獲取該值。

Part 6:

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


// [TypeError: Chaining cycle detected for promise #<Promise>]

知識點:.then 或 .catch 返回的值不能是 promise 本身,否則將導致無限循環。

Part 7:

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


// then: Error: error!

知識點:在 .then 或 .catch 中返回錯誤對象不會引發錯誤,因此後續的 .catch 不會捕獲該錯誤對象,您需要更改爲以下對象之一:

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

因爲返回任何非promise值都將被包裝到一個Promise對象中,也就是說,返回 new Error('error') 等同於返回Promise.resolve(new Error('error'))

Part 8:

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


  // 1

知識點:.then 或 .catch 的參數應爲函數,而傳遞非函數將導致值的結果被忽略,例如 .then(2)或 .then(Promise.resolve(3))

Part 9:

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


//   fail2:  Error: Error after success

知識點:.then 可以接受兩個參數,第一個是處理成功的函數,第二個是處理錯誤的函數。 .catch 是編寫 .then 的第二個參數的便捷方法,但是在使用中要注意一點:.then 第二個錯誤處理函數無法捕獲第一個成功函數和後續函數拋出的錯誤。 catch 捕獲先前的錯誤。 當然,如果要重寫,下面的代碼將起作用:

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

Part 10:

process.nextTick(() => {
  console.log('1')
})
Promise.resolve()
  .then(() => {
    console.log('2')
  })
setImmediate(() => {
  console.log('3')
})
console.log('4');


// 4 1 2 3

知識點:process.nextTick 和 promise.then 都屬於微任務,而 setImmediate 屬於宏任務,它在事件循環的檢查階段執行。 在事件循環的每個階段(宏任務)之間執行微任務,並且事件循環的開始執行一次。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章