Promise 是異步編程的一種解決方案。react
/** * 屬性 */
Promise.length
Promise.prototype
/** * 方法 */
Promise.all(iterable) // 全部成功觸發成功 任何失敗觸發失敗
Promise.race(iterable) // 任意一個成功或失敗後觸發
Promise.reject(reason)
Promise.resolve(value)
/** * 原型 */
Promise.prototype.constructor
//方法
Promise.prototype.catch(onRejected)
Promise.prototype.then(onFulfilled, onRejected)
Promise.prototype.finally(onFinally)
複製代碼
Promise 有三種狀態編程
pending 是初始狀態,執行 resolve/reject 會進入對應狀態,若是不執行,責一直爲 pending 狀態跨域
例以下面代碼,promise 將一直在 pending 狀態,不會執行 then/catch.promise
new Promise(function (resolve, reject) { })
.then(res => console.log(res))
.catch(err => console.log(err))
複製代碼
resolve 意味着操做成功完成, 若是有 .then,值會傳入 .then 的第一個參數函數裏。瀏覽器
如網絡
new Promise(function (resolve, reject) {
resolve(1)
})
.then(res => console.log(res))
複製代碼
then 的第一個參數是成功的回調,第一個參數的返回值會影響接下來鏈的去向。第一個參數的返回值通常有三種狀況數據結構
例如想要在當前 then 終止,能夠這樣操做:異步
.then((res) => new Promise(() => {}))
複製代碼
reject 意味着操做失敗。異步編程
使用 .catch 會捕獲到錯誤信息。函數
與代碼報錯(如 undefined.a)不一樣的是, 代碼報錯若是不使用 catch 捕獲,會向外傳遞,最終傳遞到根結點;而 reject 屬於 promise 錯誤,即便不使用 catch 捕獲也不會對全局有影響。
先來看幾個問題:
帶着這幾個問題,來看看 fetch。
fetch 返回值是 promise,因此有三種狀態 pending、resolve、reject.
咱們還發現,請求失敗時,只能 catch 到最後一行錯誤, 如圖
捕獲後
實現有幾個難點,
試了下,Promise.reject('xxx') 這樣的報錯方式雖然是微觀任務,可是老是在.then以後纔在控制檯輸出,更像是宏觀任務。因此也加個setTImeout宏觀任務調至後面。
var fetch = function () {
return new Promise(function (resolve, reject) {
setTimeout(function () {
if ('請求成功 200') {
resolve('Response數據結構');
} else if ('請求成功 404,500等') {
Promise.reject('GET xxxxxxxx 404');
setTimeout(function () {
resolve('Response數據結構');
});
}
})
})
}
複製代碼
一樣加個 setTimeout
var fetch = function () {
return new Promise(function (resolve, reject) {
setTimeout(function () {
if ('請求成功 200') {
resolve('Response數據結構');
} else if ('請求成功 404,500等') {
Promise.reject('GET xxxxxxxx 404');
setTimeout(function () {
resolve('Response數據結構');
});
} else if ('請求失敗') {
Promise.reject('Access to fetch xxxxx with CORS disabled.');
Promise.reject('GET xxxxx net::ERR_FAILED');
setTimeout(function () {
reject('TypeError: Failed to fetch');
});
}
})
})
}
複製代碼
仍是有些問題,咱們實現的由於在promise 中,錯誤會有前綴 Uncaught (in promise)。瀏覽器客戶端應該有更好的實現方式。
最後總結一下 fetch 的三種狀況
拋錯均不影響代碼執行,與 undefined.a 不一樣。