沐鳴登錄_這 10 個片段,有助於你理解 ES 中的 Promise

在開發中,了解 JavaScript 和 Promise 基礎,有助於提高我們的編碼技能,今天,我們一起來看看下面的 10 片段,相信看完這 10 個片段有助於我們對 Promise 的理解。

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

片段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->fulfilled 或pending->rejected,就可以再次更改它。 prom1與prom2不同,並且兩者都返回新的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調用,也只能執行一次resolve或reject ,剩下的不會執行。

片段 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本身,否則將導致無限循環。

片段 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.nextTick和promise.then都屬於微任務,而setImmediate屬於宏任務,它在事件循環的檢查階段執行。 在事件循環的每個階段(宏任務)之間執行微任務,並且事件循環的開始執行一次。

原文:http://jamesknelson.com/

作者:Jay Chow

譯者:前端小智

站長推薦

1.雲服務推薦: 國內主流雲服務商,各類雲產品的最新活動,優惠券領取。地址:阿里雲騰訊雲華為雲

2.廣告聯盟: 整理了目前主流的廣告聯盟平台,如果你有流量,可以作為參考選擇適合你的平台點擊進入

鏈接: http://www.fly63.com/article/detial/8455