Promise問答

本文主要針對這篇文章提出的問題,作個解答。html

1.瞭解 Promise 嗎?git

  Promise是一種異步編程的解決方案,有三種狀態,pending(進行中)、resolved(已完成)、rejected(已失敗)。當Promise的狀態由pending轉變爲resolved或reject時,會執行相應的方法。es6

  特色:github

  一、只有異步操做的結果,能夠決定當前是哪種狀態,任務其餘操做都沒法改變這個狀態,也是「Promise」的名稱的由來。編程

  二、狀態一旦改變,就沒法再次改變狀態。promise

2.Promise 解決的痛點是什麼?異步

  一、回調地獄帶來的負面做用:代碼臃腫,可讀性差,只能在回調裏處理異常。。async

  二、事件,事件的特色是若是你錯過了它,再去監聽,是得不到結果的。而Promise若是改變已經發生了,你再對Promise對象添加回調函數,也會當即獲得這個結果。異步編程

3.Promise 解決的痛點還有其餘方法能夠解決嗎?若是有,請列舉。函數

  setTimeout、事件監聽、回調函數、Generator函數,async/await

  一、setTimeout:缺點不精確,只是確保在必定時間後加入到任務隊列,並不保證立馬執行。只有執行引擎棧中的代碼執行完畢,主線程纔會去讀取任務隊列。

  二、事件監聽:任務的執行不取決於代碼的順序,而取決於某個事件是否發生。 

  三、Generator函數雖然將異步操做表示得很簡潔,可是流程管理卻不方便(即什麼時候執行第一階段、什麼時候執行第二階段)。即如何實現自動化的流程管理。

  四、async/await

4.Promise如何使用

  一、建立實例

//創造一個Promise實例。
const promise = new Promise(function(resolve, reject) {
  // ... some code

  if (/* 異步操做成功 */){
    resolve(value);
  } else {
    reject(error);
  }
});

//Promise實例生成之後,能夠用then方法分別指定resolved狀態和rejected狀態的回調函數。
promise.then(function(value) {
  // success
}, function(error) {
  // failure
});

  二、可用Promise的try和catch方法預防異常

Promise.try(database.users.get({id: userId}))
  .then(...)
  .catch(...)

5.Promise 經常使用的方法,方法的做用?

  一、Promise.prototype.then()、Promise.prototype.catch()、Promise.prototype.finally()、Promise.all()、Promise.race()、Promise.resolve()、Promise.reject()。

  二、Promise.all方法用於將多個 Promise 實例,包裝成一個新的 Promise 實例。

const p = Promise.all([p1, p2, p3]);

  //只有p一、p二、p3的狀態都變成fulfilled,p的狀態纔會變成fulfilled。

  三、Promise.race方法一樣是將多個 Promise 實例,包裝成一個新的 Promise 實例。

const p = Promise.race([p1, p2, p3]);

  //只有p一、p二、p3有一個實例率先改變狀態,p的狀態就跟着改變。

  //下面是一個例子,如何指定時間內沒有獲取結果,就將promise的狀態變爲reject,不然變爲resolve。

const p = Promise.race([
  fetch('/resource-that-may-take-a-while'),
  new Promise(function (resolve, reject) {
    setTimeout(() => reject(new Error('request timeout')), 5000)
  })
]);

p
.then(console.log)
.catch(console.error);

6.Promise 在事件循環中的執行過程是怎樣的?

  首先什麼是事件循環?看下這篇文章,http://www.javashuo.com/article/p-kqwysvls-h.html。簡要提取下就是:

   從代碼執行順序的角度來看,程序最開始是按代碼順序執行代碼的,遇到同步任務,馬上執行;遇到異步任務,則只是調用異步函數發起異步請求。此時,異步任務開始執行異步操做,執行完成後到消息隊列中排隊。程序按照代碼順序執行完畢後,查詢消息隊列中是否有等待的消息。若是有,則按照次序從消息隊列中把消息放到執行棧中執行。執行完畢後,再從消息隊列中獲取消息,再執行,不斷重複。

  因爲主線程不斷的重複得到消息、執行消息、再取消息、再執行。因此,這種機制被稱爲事件循環

   promise的構造部分是同步執行,script(主程序代碼)—>process.nextTick—>Promises...——>setTimeout——>setInterval——>setImmediate——> I/O——>UI rendering。引用文章:https://github.com/forthealllight/blog/issues/5

setTimeout(function(){console.log(1)},0);

new Promise(function(resolve,reject){
   console.log(2);
   resolve();
}).then(function(){console.log(3)
}).then(function(){console.log(4)});

process.nextTick(function(){console.log(5)});

console.log(6);

//輸出2,6,5,3,4,1

7.能不能手寫一個 Promise 的 polyfill

  https://github.com/stefanpenner/es6-promise

相關文章
相關標籤/搜索