摘要:實例具有方法方法是定義在原型對象上的它的作用是為實例添加狀態改變時的回調函數。一個請求的例子出錯了方法是的別名,用于指定發生錯誤時的回調函數。那個率先改變的實例的返回值,就傳遞給的回調函數。
Promise 是異步編程的一種解決方案,其他的異步編程解決方案還有——回調函數、事件監聽、發布訂閱,以及ES6新增的Generator 。
Promise的狀態http://www.ruanyifeng.com/blo...
http://es6.ruanyifeng.com/#do...
Pending(進行中)
Resolved (已完成)
Rejected (已失敗)
Promise的特點對象的狀態不受外界影響。
一旦狀態改變,就不會再變,任何時候都可以得到這個結果。
Promise的用法var promise = new Promise(function(resolve, reject) { // ... some code if (/* 異步操作成功 */){ resolve(value); } else { reject(error); } });
注意:
resovle和reject函數都是由js引擎提供的函數不用自己定義。
其中 resovle函數的作用是將Promise對象從進行中狀態轉換為已完成,reject函數將Promise對象從進行中狀態轉換為已失敗狀態。
Promise.prototype.then()Promise 實例具有then方法,then方法是定義在原型對象Promise.prototype上的,它的作用是為 Promise 實例添加狀態改變時的回調函數。
延續上面的代碼:
promise.then(function(res) { console.log(res) }, function(err) { console.log(err) })
then對象接收兩個回調函數作為參數,第一個回調函數是resovle的回調,第二個回調函數是reject的回調。即,一個用于處理狀態為已完成的邏輯,另一個用于處理已失敗的邏輯。
一個Ajax請求的例子:
var getJSON = function(url) { var promise = new Promise(function(resolve, reject){ var client = new XMLHttpRequest(); client.open("GET", url); client.onreadystatechange = handler; client.responseType = "json"; client.setRequestHeader("Accept", "application/json"); client.send(); function handler() { if (this.readyState !== 4) { return; } if (this.status === 200) { resolve(this.response); } else { reject(new Error(this.statusText)); } }; }); return promise; }; getJSON("/posts.json").then(function(json) { console.log("Contents: " + json); }, function(error) { console.error("出錯了", error); });Promise.prototype.catch()
Promise.prototype.catch方法是.then(null, rejection)的別名,用于指定發生錯誤時的回調函數。不是指then方法的別名而是指resovle的回調函數為null的then方法的別名。
通常推薦使用catch方法來捕獲異常,而不是使用reject的回調函數。
// 不推薦的寫法 promise .then(function(data) { // success }, function(err) { // error }); // 推薦的寫法 promise .then(function(data) { // success }) .catch(function(err) { // error });
使用catch方法來接收錯誤信息的好處是,Promise 對象的錯誤具有“冒泡”性質,會一直向后傳遞,直到被捕獲為止。所以一個catch可以捕獲鏈式調用中多個Promise對象拋出的異常。
鏈式調用當有幾個異步操作需要鏈式調用時,promise是支持的。
一個簡單的鏈式調用的例子:
getJSON("/post/1.json").then(function(post) { return getJSON(post.commentURL); }).then(function funcA(comments) { console.log("Resolved: ", comments); }, function funcB(err){ console.log("Rejected: ", err); });
Promise的then函數,返回的是一個新的Promise對象。如果返回的對象不是Promise對象會是什么效果呢?
以下是一些測驗代碼:
var promise = new Promise(function(resolve, reject) { let a = "111"; resolve(a); }); promise.then(function(res) { return null; }).then(function(res){ console.log(res); }).catch(function(err) { console.log(err); }) // null
var b = function() { console.log("bb"); } var promise = new Promise(function(resolve, reject) { let a = "111"; resolve(a); }); promise.then(function(res) { return b(); }).then(function(res){ console.log(res); }) // bb // undefined
可以看出,如果then retrun的不是一個Promise函數時,并不會報錯,也沒有拋出異常,相當于一個沒有執行reject和resovle的Promise對象(個人理解,有失偏頗。望自慎重,擇善從之。)。
Promise.all()在某些時候,我們需要執行多個異步操作。這些異步操作可能有以下幾種關系:
互不關聯
逐個依賴
部分依賴
結果依賴(指需要獲得所以返回的結果進行下一步的操作)
Promise.all方法用于將多個 Promise 實例,包裝成一個新的 Promise 實例。可以用來解決上面的4關系。
互不關聯最好分開調用,部分依賴、逐個依賴用鏈式調用。
Promise.all接收一個Promise數組作為參數,即數組中的值都是Promise對象,如果不是就會先調用Promise.resovle方法,將參數轉為Promise實例。
// 生成一個Promise對象的數組 var promises = [2, 3, 5, 7, 11, 13].map(function (id) { return getJSON("/post/" + id + ".json"); }); Promise.all(promises).then(function (posts) { // ... }).catch(function(reason){ // ... });
只有當所有的Promise對象都返回resovle時才會執行then方法,只要有一個Pormise對象返回的是reject,就執行catch。
ps: 還有Promise.race()方法,此方法和Promise.all()不同之處時,只要傳入的Promise數組中有一個實例率先改變狀態,p的狀態就跟著改變。那個率先改變的 Promise 實例的返回值,就傳遞給p的回調函數。可用于限制請求的最大反應時間。
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(response => console.log(response)); p.catch(error => console.log(error)); // 如果超過5秒就返回請求超時Promise.resolve()和Promise.reject()
這兩個方法返回一個新的Promise實例,resovle方法返回的實例狀態為resolve,同理reject方法返回reject。
都接收一個參數作為現有的對象,此參數可以為任何值包括null,undefined。
根據接收的參數,兩種方法都會做出不同的處理。在此不做詳細的介紹了,有興趣的可以去看看
http://es6.ruanyifeng.com/#do...
Promise.resolve("foo") // 等價于 new Promise(resolve => resolve("foo"))finally()
此方法用于最后執行,不Promise的狀態如何,都會執行的操作(還有這種操作?)。在node中可用于關閉服務器或者數據庫連接。在瀏覽器中可用于需要在異步函數返回之后執行的操作。
var p = new Promise(function(resovle.reject){ resovle("is resovle"); }); p.then(function(res) { console.log(res) }).finally(function() { console.log("is finally"); })
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/83664.html
摘要:直到最近,我們仍然在用簡單的回調函數來處理異步的問題。當我們只有一個異步任務的時候使用回調函數看起來還不會有什么問題。 原文地址:http://blog.getify.com/promis... 廈門旅行歸來,繼續理解Promise 在上一篇深入理解Promise五部曲:1.異步問題中,我們揭示了JS的異步事件輪詢并發模型并且解釋了多任務是如何相互穿插使得它們看起來像是同時運行的。...
摘要:標準已于年月份正式定稿了,并廣泛支持最新的特性異步函數。為了領會,我們需要回到普通回調函數中進一步學習。從此編寫回調函數不再那么痛苦。回調是一個函數,可以將結果傳遞給函數并在該函數內進行調用,以便作為事件的響應。 ES2017標準已于2017年6月份正式定稿了,并廣泛支持最新的特性:異步函數。如果你曾經被異步 JavaScript 的邏輯困擾,這么新函數正是為你設計的。 異步函數或多或...
摘要:當時,范數稱為歐幾里得范數。更嚴格地說,范數是滿足下列性質的任意函數這條被稱為三角不等式范數的推廣除了范數之外,在機器學習中還常用范數,就是所有元素的絕對值的和。 摘要: 范數的定義和Tensorflow實現 矩陣進階 - 范數 作為快餐教程,我們盡可能多上代碼,多介紹工具,少講原理和公式。但是我也深知這樣是無法講清楚的,畢竟問題的復雜度擺在這里呢。與大家一起在Tensorflow探索...
閱讀 3085·2021-09-22 15:20
閱讀 2608·2019-08-30 15:54
閱讀 1972·2019-08-30 14:06
閱讀 3120·2019-08-30 13:05
閱讀 2464·2019-08-29 18:36
閱讀 576·2019-08-29 15:10
閱讀 530·2019-08-29 11:17
閱讀 827·2019-08-28 18:11