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