new Promise(function(resolve, reject){});
構造函數接受一個函數(executor)做爲參數,該函數在返回 Promise 實例以前被調用。函數的兩個參數分別是 resolve 和 reject 函數。es6
若是 executor 函數執行中拋出異常,則 Promise 視爲 rejected。數組
executor 函數返回值沒有意義。promise
相似於 jQuery.when() 方法,只有 iterable 中全部的 Promise 都被 resolve,它返回一個新的被 resolve 的 Promise,resolved 值爲 iterable 中全部 resolved 值組成的數組;或者 iterable 中只要有一個 Promise 被 reject,則馬上返回一個新的被 reject 的 Promise,rejected 值同時傳遞給新的 Promise。瀏覽器
一旦 iterable 中任何一個 Promise 被 resolve 或 reject,則當即返回一個新的被 resolve 或 reject 的 Promise。異步
返回一個 rejected Promise。async
返回一個新的 Promise。若是 value 是一個 thenable 對象(Promise),新 Promise 狀態與 thenable 一致;不然新 Promise 狀態爲 resolved,Promise 結果爲 value。函數
返回一個新的 Promise。Promise 將 rejected 值視爲一個 error,經過 catch 方法能夠捕捉 rejected 值,並將該值傳遞給 onRejected 函數。onRejected 函數返回值將做爲新 Promise 的 resolve 參數,也就是說,若是 onRejected 返回值是一個 Promise,則新 Promise 與該 Promise 狀態一致;不然新 Promise 狀態爲 resolved,結果值爲 onRejected 返回值。this
若是一個 rejected Promise 沒有調用過 catch 方法,在谷歌瀏覽器控制檯會輸出異常提示
Uncaught (in promise) 1
。prototype
返回一個新 Promise。若是 onFulfilled 和 onRejected 是函數,則使用它們的返回值做爲新 Promise 的 resolve 參數。不然新 Promise 與舊 Promise 狀態保持一致。code
雖然 then 方法能夠分別處理 resolution 和 rejection 兩種情景,但 ES6 Promise 將 rejection 更多地視做異步異常情景,所以提供 catch 方法處理 rejection 情景。
因此好的實踐是使用 then 方法處理 resolution,catch 方法處理 rejection。
// 不推薦 asyncRun().then(function(value) {}, function(error) {}); // 推薦 asyncRun().then(function(value){}).catch(function(rejected) {});
尤爲當須要連接多個 Promise 時,使用 then + catch 模式會讓代碼更加清晰。
// 不推薦 asyncRun() .then(function(value) {}, function(error) {}) .then(function(value) {}, function(error) {}) .then(function(value) {}, function(error) {}); // 推薦 asyncRun() .then(function(value){}) .then(function(value){}) .then(function(value){}) .catch(function(rejected) {});
ES6 取消了 Deferred 對象,鼓勵直接使用 Promise,並且主張 Promise 應該由它的建立者來 resolve 或 reject。
但某些場景下,Deferred 對象仍然是一種更好的選擇,尤爲是 Promise 建立者與求值者分屬不一樣對象時。
簡潔版:
function Deferred() { var self = this; var promise = this.promise = new Promise(function(resolve, reject) { self.resolve = resolve; self.reject = reject; }); this.then = this.promise.then.bind(promise); this.catch = this.promise.catch.bind(promise); this.catch(function() {}); }
完整版:
/* * @Author: laixi * @Date: 2016-11-18 11:40:06 * @Last Modified by: laixi * @Last Modified time: 2016-11-18 12:36:26 */ var Deferred = function(beforeStart) { if (!(this instanceof Deferred)) { return new Deferred(beforeStart); } var _resolve; // resolve function var _reject; // reject function var _result; // resolved value or rejected reason var _state = 'pending'; // promise status var doneCallbacks = []; var failCallbacks = []; var alwaysCallbacks = []; // create promise object var promise = new Promise(function(resolve, reject) { _resolve = resolve; _reject = reject; }); // eliminate annoying error prompt at Chrome console promise.catch(function() {}); // respectively call callbacks in done callback queue or fail callback queue promise.then(function(value) { _result = value; while (doneCallbacks.length > 0) { var callback = doneCallbacks.splice(0, 1)[0]; callback.call(promise, value); } }, function(reason) { _result = reason; while (failCallbacks.length > 0) { var callback = failCallbacks.splice(0, 1)[0]; callback.call(promise, reason); } }); // extend promise by adding done, fail, always. // ---------------------------------------------- promise.done = function(callback) { if (typeof callback === 'function') { if (_state === 'resolved') { callback.call(promise, _result); } else { doneCallbacks.push(callback); } } return promise; }; promise.fail = function(callback) { if (typeof callback === 'function') { if (_state === 'rejected') { callback.call(promise, _result); } else { failCallbacks.push(callback); } } return promise; }; promise.always = function(callback) { if (typeof callback === 'function') { if (_state === 'pending') { alwaysCallbacks.push(callback); } else { callback.call(promise, _result); } } return promise; }; this.promise = function() { return promise; }; this.state = function() { return _state; }; this.resolve = function(value) { _state = 'resolved'; _resolve.call(promise, value); }; this.reject = function(reason) { _state = 'rejected'; _reject.call(promise, reason); }; this.catch = promise.catch.bind(promise); this.then = promise.then.bind(promise); this.done = promise.done.bind(promise); this.fail = promise.fail.bind(promise); this.always = promise.always.bind(promise); if (typeof beforeStart === 'function') { beforeStart.call(this, this); } };