Promise對象能夠這樣理解。建立Promise對象表示建立了一個當即執行的代碼(一般爲ajax、jsonp這類異步代碼),並根據設立的條件(例如ajax請求狀態爲200OK)執行回調函數。Promise對象只會變爲兩種狀態,成功或失敗。並承諾這個狀態只能由resolve
和reject
來改變,其餘人不能夠改變(promise的狀態,不是指200OK這個成功,意思就是執行完resolve了,promise狀態就變成成功)。而且承諾狀態只會改變一次,狀態一旦改變就不會再改變。並承諾不管你何時提供回調函數,只要狀態改變過(執行過resolve)我就會執行回調函數,你不用擔憂由於提供回調函數過晚,而錯過了狀態的改變。ajax
let promise = new Promise(function(resolve, reject) { console.log('Promise'); resolve(); }); promise.then(function() { console.log('Resolved.'); }); console.log('Hi!'); // Promise // Hi! // Resolved
new Promise(function(resolve) { el.onclick = resolve }).then(function() { console.log('clicked') }) // 點擊el元素屢次 // clicked(只會打印一次clicked,由於不會出現兩次成功狀態)
另一個例子:json
var p1 = new Promise(function(re, rj) { rj() re() }) p1. then(function() { console.log(1) }, function() { console.log(2) }) // 2(re方法不會執行,由於狀態已經變爲失敗)
const preloadImage = function(path) { return new Promise(function(resolve, reject) { var image = new Image(); image.onload = resolve; image.onerror = reject; image.src = path; }); }; const a = preloadImage('images/1.jpeg') // 數秒後在控制檯寫下Promise的回調函數 a .then(function() { console.log('image loaded') }) // image loaded(load事件早已經觸發,可是你並無錯過他)
then方法若是沒有返回另外一個Promise對象,則默認返回一個成功狀態的新的Promise對象。若是代碼中因執行throw語句而拋出錯誤,則返回一個失敗狀態的新的Promise對象。promise
const p1 = new Promise(function(re) { re('p1') }) const p2 = new Promise(function(re) { re('p2') }) p1 .then(msg => { console.log(msg); return p2 // 返回另外一個Promise對象 }) .then(msg => { console.log(msg) }) // p1 // p2
注意是新的Promise對象。參考下面的例子。下面例子中第二個then方法沒有接受到任何參數,由於他是新的Promise對象的回調。異步
const p1 = new Promise(function(re) { re('p1') }) const p2 = new Promise(function(re) { re('p2') }) p1 .then(msg => { console.log(msg); }) .then(msg => { console.log(msg); return p2 // 返回另外一個Promise對象 }) .then(msg => { console.log(msg) }) // p1 // undefined // p2
至關於:函數
const p1 = new Promise(function(re) { re('p1') }) const p2 = new Promise(function(re) { re('p2') }) p1 .then(msg => { console.log(msg); return new Promise(function(re){ re() }) }) .then(msg => { console.log(msg); return p2 // 返回另外一個Promise對象 }) .then(msg => { console.log(msg) }) // p1 // undefined // p2
Promise對象的狀態傳遞是不會被攔截的。例如代碼中出現錯誤會返回一個失敗狀態的Promise對象,可是這個失敗狀態不會被攔截,會一直傳遞到失敗回調函數去執行爲止。jsonp
const p1 = new Promise(function(re) { re('p1') }) p1.then(function(p) { console.log(p) throw new Error('erro') }) .then(function() { console.log(1) // 這個then方法被跳過,由於傳遞下來的是失敗狀態的Promise對象 }) .catch(function(er){ console.log(er) }) // p1 // erro