摘要:定義是抽象異步處理對象以及對其進(jìn)行各種操作的組件簡言之,使用就是將中異步的方式變換成同步來操作。如果對異步回調(diào)函數(shù)進(jìn)行同步調(diào)用的話,處理順序可能會與預(yù)期不符,可能帶來意料之外的后果。如果想在將來某時(shí)刻調(diào)用異步回調(diào)函數(shù)的話,可以使用等異步。
promise定義
Promise是抽象異步處理對象以及對其進(jìn)行各種操作的組件
簡言之,使用Promise就是將javascript中異步的方式變換成同步來操作。Promise則是把類似的異步處理對象和處理規(guī)則進(jìn)行規(guī)范化, 并按照采用統(tǒng)一的接口來編寫,規(guī)定方法之外的寫法都會報(bào)錯。簡單的示例:
var promise = getAsyncPromise("fileA.txt"); //處于Pending狀態(tài),既不是resolve也不是reject的狀態(tài)。是promise對象剛被創(chuàng)建后的初始化狀態(tài) promise.then(function(result){ // 獲取文件內(nèi)容成功時(shí)的處理 成功時(shí)狀態(tài)為onFulfilled }).catch(function(error){ // 獲取文件內(nèi)容失敗時(shí)的處理 失敗時(shí)狀態(tài)為onRejected });
其中,then和catch代表函數(shù)執(zhí)行成功和失敗的預(yù)設(shè)操作
構(gòu)建promise對象,使用new關(guān)鍵字var promise = new Promise(function(resolve, reject) { // 異步處理 // 處理結(jié)束后、調(diào)用resolve 或 reject });對象方法 then
promise.then(onFulfilled, onRejected); //onFulfilled函數(shù)會在promise對象的revolve狀態(tài)調(diào)用,onRejected為在promise對象reject狀態(tài)下調(diào)用 promise.catch(function());//catch用來代替onRejected拋出錯誤promise對象中內(nèi)置部分靜態(tài)方法
如Promise.all() , Promise.race,Promise.resolve(),Promise.reject等
創(chuàng)建XHR的promise對象function getURL(URL) { return new Promise(function (resolve, reject) { var req = new XMLHttpRequest(); req.open("GET", URL, true); req.onload = function () { if (req.status === 200) { resolve(req.responseText);//傳入resolve中的參數(shù)會在狀態(tài)改變的時(shí)候,傳到then中 } else { reject(new Error(req.statusText)); } }; req.onerror = function () { reject(new Error(req.statusText)); }; req.send(); }); } // 運(yùn)行示例 var URL = "http://httpbin.org/get"; getURL(URL).then(function onFulfilled(value){ console.log(value); }).catch(function onRejected(error){ console.error(error); });Promise.resolve
作用1. Promise.resolve 是 new Promise(func)的快捷方式,如Promise.resolve(42); 與 new Promise(function(resolve){ resolve(42);});
作用2. 將thenable 對象轉(zhuǎn)換為promise對象。thenable指的是一個(gè)具有 .then方法的對象。
Promise.reject(new Error("出錯了"))
等價(jià)于
new Promise(function(resolve,reject){ reject(new Error("出錯了")); });
使用
Promise.reject(new Error("BOOM!")).catch(function(error){ console.error(error); });promise對象立刻進(jìn)入resolve狀態(tài)
var promise = new Promise(function (resolve){ console.log("inner promise"); // 1 resolve(42); }); promise.then(function(value){ console.log(value); // 3 }); console.log("outer promise"); // 2
輸出結(jié)果為 1,2,3; 即使resolve立即執(zhí)行,得出的結(jié)果也在下一個(gè)時(shí)間環(huán)里,需要等到下一周期才能執(zhí)行
1.絕對不能對異步回調(diào)函數(shù)(即使在數(shù)據(jù)已經(jīng)就緒)進(jìn)行同步調(diào)用。
2.如果對異步回調(diào)函數(shù)進(jìn)行同步調(diào)用的話,處理順序可能會與預(yù)期不符,可能帶來意料之外的后果。
3.對異步回調(diào)函數(shù)進(jìn)行同步調(diào)用,還可能導(dǎo)致棧溢出或異常處理錯亂等問題。
4.如果想在將來某時(shí)刻調(diào)用異步回調(diào)函數(shù)的話,可以使用 setTimeout 等異步API。
對比三段代碼:
第一段:直接判斷文件是否加載完成
function onReady(fn) { var readyState = document.readyState; if (readyState === "interactive" || readyState === "complete") { fn(); } else { window.addEventListener("DOMContentLoaded", fn); } } onReady(function () { console.log("DOM fully loaded and parsed"); }); console.log("==Starting==");
第二段:使用setTimeout轉(zhuǎn)同步為異步操作
function onReady(fn) { var readyState = document.readyState; if (readyState === "interactive" || readyState === "complete") { setTimeout(fn, 0); //使用setTimeout轉(zhuǎn)化同步函數(shù)為異步函數(shù) } else { window.addEventListener("DOMContentLoaded", fn); } } onReady(function () { console.log("DOM fully loaded and parsed"); }); console.log("==Starting==");
第三段:使用promise的resolve將統(tǒng)一為異步的方式,減少判斷
function onReadyPromise() { return new Promise(function (resolve, reject) { var readyState = document.readyState; if (readyState === "interactive" || readyState === "complete") { resolve(); } else { window.addEventListener("DOMContentLoaded", resolve); } }); } onReadyPromise().then(function () { console.log("DOM fully loaded and parsed"); }); console.log("==Starting==");
關(guān)于傳遞參數(shù)promise的寫法
function doubleUp(value) { return value * 2; } function increment(value) { return value + 1; } function output(value) { console.log(value);// => (1 + 1) * 2 } var promise = Promise.resolve(1);//構(gòu)造一個(gè)返回參數(shù)為1的promise對象 promise .then(increment) //此時(shí)increment函數(shù)中傳的vaule值為1 .then(doubleUp) //此時(shí)doubleUp函數(shù)中傳的vaule值為2 .then(output) //此時(shí)doubleUp函數(shù)中傳的vaule值為 4 .catch(function(error){ // promise chain中出現(xiàn)異常的時(shí)候會被調(diào)用 console.error(error); });
Promise.resolve 和Promise.reject會對函數(shù)中return返回的值進(jìn)行包裝,最終then返回的結(jié)果都是新創(chuàng)建的promise對象
Promise.all的使用
function getURL(URL) { return new Promise(function (resolve, reject) { var req = new XMLHttpRequest(); req.open("GET", URL, true); req.onload = function () { if (req.status === 200) { resolve(req.responseText); } else { reject(new Error(req.statusText)); } }; req.onerror = function () { reject(new Error(req.statusText)); }; req.send(); }); } var request = { comment: function getComment() { return getURL("http://azu.github.io/promises-book/json/comment.json").then(JSON.parse); }, people: function getPeople() { return getURL("http://azu.github.io/promises-book/json/people.json").then(JSON.parse); } }; function main() { return Promise.all([request.comment(), request.people()]); } // 運(yùn)行示例 main().then(function (value) { console.log(value); }).catch(function(error){ console.log(error); });
證明Promise.all的promise數(shù)組是同時(shí)開始執(zhí)行的
// `delay`毫秒后執(zhí)行resolve function timerPromisefy(delay) { return new Promise(function (resolve) { setTimeout(function () { resolve(delay); }, delay); }); } var startDate = Date.now(); // 所有promise變?yōu)閞esolve后程序退出 Promise.all([ timerPromisefy(1), timerPromisefy(32), timerPromisefy(64), timerPromisefy(128) ]).then(function (values) { console.log(Date.now() - startDate + "ms"); // 約128ms console.log(values); // [1,32,64,128] });
Promise.race 只要有一個(gè)promise對象進(jìn)入 FulFilled 或者 Rejected 狀態(tài)的話,就會繼續(xù)進(jìn)行后面的處理
// `delay`毫秒后執(zhí)行resolve function timerPromisefy(delay) { return new Promise(function (resolve) { setTimeout(function () { resolve(delay); }, delay); }); } // 任何一個(gè)promise變?yōu)閞esolve或reject 的話程序就停止運(yùn)行 Promise.race([ timerPromisefy(1), timerPromisefy(32), timerPromisefy(64), timerPromisefy(128) ]).then(function (value) { console.log(value); // => 1 }); //代碼第二段 var winnerPromise = new Promise(function (resolve) { setTimeout(function () { console.log("this is winner"); resolve("this is winner"); }, 4); }); var loserPromise = new Promise(function (resolve) { setTimeout(function () { console.log("this is loser"); resolve("this is loser"); }, 1000); }); // 第一個(gè)promise變?yōu)閞esolve后程序停止 Promise.race([winnerPromise, loserPromise]).then(function (value) { console.log(value); // => "this is winner" });
不能進(jìn)行錯誤處理的onRejected
function throwError(value) { // 拋出異常 throw new Error(value); } // <1> onRejected不會被調(diào)用 function badMain(onRejected) { return Promise.resolve(42).then(throwError, onRejected); } // <2> 有異常發(fā)生時(shí)onRejected會被調(diào)用 function goodMain(onRejected) { return Promise.resolve(42).then(throwError).catch(onRejected); } // 運(yùn)行示例 badMain(function(){ console.log("BAD"); }); goodMain(function(){ console.log("GOOD"); });
說明:上面代碼中<1>中throwError 拋出了異常,onRejected 指定的函數(shù)也不會被調(diào)用
.then 和 .catch 都會創(chuàng)建并返回一個(gè) 新的 promise對象。 Promise實(shí)際上每次在方法鏈中增加一次處理的時(shí)候所操作的都不是完全相同的promise對象。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/78607.html
摘要:從最開始的到封裝后的都在試圖解決異步編程過程中的問題。為了讓編程更美好,我們就需要引入來降低異步編程的復(fù)雜性。異步編程入門的全稱是前端經(jīng)典面試題從輸入到頁面加載發(fā)生了什么這是一篇開發(fā)的科普類文章,涉及到優(yōu)化等多個(gè)方面。 TypeScript 入門教程 從 JavaScript 程序員的角度總結(jié)思考,循序漸進(jìn)的理解 TypeScript。 網(wǎng)絡(luò)基礎(chǔ)知識之 HTTP 協(xié)議 詳細(xì)介紹 HTT...
showImg(https://segmentfault.com/img/bVbfGSV?w=719&h=718); showImg(https://segmentfault.com/img/bVbfGTc?w=801&h=552); showImg(https://segmentfault.com/img/bVbfGTq?w=1017&h=501);
摘要:比如正則表示匹配這樣一個(gè)字符串第一個(gè)字符是,接下來是到個(gè)字符,最后是字符。其實(shí)現(xiàn)的方式是使用字符組。具體形式如下,其中和是子模式,用管道符分隔,表示其中任何之一。 貪婪模式: 在使用修飾匹配次數(shù)的特殊符號時(shí),有幾種表示方法可以使同一個(gè)表達(dá)式能夠匹配不同的次數(shù),比如:{m,n}, {m,}, ?, *, +,具體匹配的次數(shù)隨被匹配的字符串而定。這種重復(fù)匹配不定次數(shù)的表達(dá)式在匹配過程中,總...
摘要:寫在前面這一章的順序?qū)τ谖唇佑|過使用過的童鞋而言略抽象了,前邊幾章主要為了說明和之前的異步方式相比有什么優(yōu)勢和它能解決什么問題,后邊才詳解的設(shè)計(jì)和各種場景下如何使用。建議先了解和簡單使用過后再閱讀,效果更佳。 寫在前面:Promise這一章的順序?qū)τ谖唇佑|過使用過Promise的童鞋而言略抽象了,前邊幾章主要為了說明Promise和之前的異步方式相比有什么優(yōu)勢和它能解決什么問題,后邊才...
摘要:對象是一個(gè)返回值的代理,這個(gè)返回值在對象創(chuàng)建時(shí)未必已知。這使得異步方法可以像同步方法那樣返回值異步方法會返回一個(gè)包含了原返回值的對象來替代原返回值。 前言 近來參加校招筆試,發(fā)現(xiàn)有好幾道關(guān)于Promise的題目。然而我都沒有了解過。所以,這篇文章以網(wǎng)易筆試的一道題開始,記錄關(guān)于Promise的那些事。文章地址:http://lsxj615.com/2016/08/04... 筆試題 c...
閱讀 1684·2021-11-23 09:51
閱讀 3697·2021-09-26 09:46
閱讀 2198·2021-09-22 10:02
閱讀 1999·2019-08-30 15:56
閱讀 3395·2019-08-30 12:51
閱讀 2286·2019-08-30 11:12
閱讀 2122·2019-08-29 13:23
閱讀 2380·2019-08-29 13:16