這 10 個片斷,有助於你理解 ES 中的 Promise

做者:Jay Chow
譯者:前端小智
來源:jamesknelson

點贊再看,養成習慣前端

本文 GitHub https://github.com/qq44924588... 上已經收錄,更多往期高贊文章的分類,也整理了不少個人文檔,和教程資料。歡迎Star和完善,你們面試能夠參照考點複習,但願咱們一塊兒有點東西。git

在開發中,瞭解 JavaScript 和 Promise 基礎,有助於提升咱們的編碼技能,今天,咱們一塊兒來看看下面的 10 片斷,相信看完這 10 個片斷有助於咱們對 Promise 的理解。es6

片斷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異步執行。github

片斷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>}
// __proto__: Promise
// [[PromiseStatus]]: "resolved"
// [[PromiseValue]]: "success"

// 2 秒後還會在打一遍上面的兩個

promise 有三種不一樣的狀態:面試

  • pending
  • fulfilled
  • rejected

一旦狀態更新,pending->fulfilledpending->rejected,就能夠再次更改它。 prom1prom2不一樣,而且二者都返回新的Promise狀態。promise

片斷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

即便reject後有一個resolve調用,也只能執行一次resolvereject ,剩下的不會執行。服務器

片斷 4:

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

// 1
// 2

Promises 能夠連接調用,當提到連接調用 時,咱們一般會考慮要返回 this,但Promises不用。 每次 promise 調用.then.catch時,默認都會返回一個新的 promise,從而實現連接調用。異步

片斷 5:

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的每次調用都將直接獲取該值。函數

片斷 6:

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

// [TypeError: Chaining cycle detected for promise #<Promise>]
// Uncaught SyntaxError: Identifier 'promise' has already been declared
//    at <anonymous>:1:1
// (anonymous) @ VM218:1

.then.catch返回的值不能是promise自己,不然將致使無限循環。工具


你們都說簡歷沒項目寫,我就幫你們找了一個項目,還附贈【搭建教程】

我和阿里雲合做服務器,折扣價比較便宜:89/年,223/3年,比學生9.9每個月還便宜,買了搭建個項目,熟悉技術棧比較香(老用戶用家人帳號買就行了,我用我媽的)推薦買三年的划算點,點擊本條就能夠查看


片斷 7:

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

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

.then.catch中返回錯誤對象不會引起錯誤,所以後續的.catch不會捕獲該錯誤對象,須要更改成如下對象之一:

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

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

片斷 8:

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

  // 1

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

片斷 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
//     at success (<anonymous>:4:13)

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

片斷 10:

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

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

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


代碼部署後可能存在的BUG無法實時知道,過後爲了解決這些BUG,花了大量的時間進行log 調試,這邊順便給你們推薦一個好用的BUG監控工具 Fundebug

原文:http://jamesknelson.com/grokk...


交流

乾貨系列文章彙總以下,以爲不錯點個Star,歡迎 加羣 互相學習。

https://github.com/qq44924588...

我是小智,公衆號「大遷世界」做者,對前端技術保持學習愛好者。我會常常分享本身所學所看的乾貨,在進階的路上,共勉!

關注公衆號,後臺回覆福利,便可看到福利,你懂的。

clipboard.png

相關文章
相關標籤/搜索