本文主要針對這篇文章提出的問題,作個解答。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。