ES6新功能:JavaScript中內建的延遲物件Promise 程式碼詳細介紹
Promise的基本使用:
利用Promise是解決JS非同步執行時候回呼函數巢狀回呼函數的問題, 更簡潔地控制函數執行流程;
透過new實例化Promise, 建構函數需要兩個參數, 第一個參數為函數執行成功以後執行的函數resolve,第二個函數為函數執行失敗以後執行的函數reject:
new Promise(function(resolve , reject) { });
透過Promise,我們把回呼函數用線性的方式寫出來,而不是一層套一層, 這個函數有四層回呼;
fn("args", function(a) { fn1("foo", function(b) { fn2("bar", function(c) { fn3("baz", function(d) { alert("回调成功,获知的内容为:"+a+b+c+d) }) }) }) })
以上的Demo只有包含成功的回呼, 如果失敗的回呼也算的話, 也就更麻煩了;
如果使用Promise的方式,我們可以改裝成線性的程式碼,更符合閱讀的習慣,只要在then函數下寫邏輯即可;
new Promise(function(resolve , reject) { resolve(1); }).then(function(val) { console.log(val); return new Promise(function(resolve , reject) { resolve(2); }); }).then(function(val) { console.log(val); return new Promise(function(resolve , reject) { resolve(3); }); }).then(function(val) { console.log(val); return new Promise(function(resolve , reject) { resolve(4); }); }).then(function(val) { console.log(val); });
這是一個ajax異步獲取資料的例子, 我們使用了回呼函數;
<html> <head> <meta charset="utf-8"> </head> <body> <script> var callback = function(res) { console.log(res); }; var ajax = function(url, callback) { var r = new XMLHttpRequest(); r.open("GET", url, true); r.onreadystatechange = function () { if (r.readyState != 4 || r.status != 200) return; var data = JSON.parse(r.responseText); callback(data); }; r.send(); }; //执行请求: ajax("http://www.filltext.com?rows=10&f={firstName}", callback); //再做别的事情; </script> </body> </html>
因為ES6內建了Promise, 我們可以把以上的callback改寫成promise的方式, 首先ajax函數回傳一個Promise物件;
<html> <head> <meta charset="utf-8"> </head> <body> <script> var callback = function(res) { console.log(res); }; var ajax = function(url) { return new Promise(function(resolve, reject) { var r = new XMLHttpRequest(); r.open("GET", url, true); r.onreadystatechange = function () { if (r.readyState != 4 || r.status != 200) return; var data = JSON.parse(r.responseText); resolve(data); }; r.send(); }) }; //执行请求: ajax("http://www.filltext.com?rows=10&f={firstName}").then(function(data) { callback(data); }); //再做别的事情; </script> </body> </html>
Promise實例的三種狀態:
每一個實例化的Promise都有三個狀態;pending(等待) rejected(拒絕) resolved(解決) ,預設的狀態為pending,如果執行了resolve(), 那麼這個promise的狀態會變為resolve,如果執行了reject(), 那麼這個promise的狀態就會變成rejected, 而且這些狀態是不可撤銷的,一經更改,不會再變了;
then方法:
promise有一個then方法,then方法接收兩個參數, 第一個為函數的成功回調, 第二個為函數的失敗回呼:
var promise = new Promise(function(resolve , reject) { resolve(); //执行成功回调; }); console.log(0); promise.then(function(val) { console.log(1); }, function() { console.log("失败"); }); console.log("2");
var promise = new Promise(function(resolve , reject) { reject(); }); console.log(0); promise.then(function(val) { console.log(1); }, function() { console.log("失败"); }); console.log("2");
then方法每一次都是傳回不同的Promise實例,then的第一個參數是成功回調, 這個成功回呼的參數為: 上一個Promise實例執行resolve方法的參數;
一般來說, then方法會傳回目前的 promise , 如果在then方法裡面return 一個新的Promise實例,那麼此時的then返回的就是新的Promise實例, 利用這個特性,就可以實現多層回調;
new Promise(function(resolve , reject) { resolve(1); }).then(function(val) { console.log(val); return new Promise(function(resolve , reject) { resolve(2); }); }).then(function(val) { console.log(val); return new Promise(function(resolve , reject) { resolve(3); }); }).then(function(val) { console.log(val); return new Promise(function(resolve , reject) { resolve(4); }); }).then(function(val) { console.log(val); });
不管程式碼是異步還是同步的, 都可以用Promise的then方法, 同步的程式碼直接寫在then方法第一個參數, 把需要參數透過resolve傳給下一個then方法,
#如果是異步的程式碼,就直接return一個Promise實例:
new Promise(function(resolve , reject) { resolve(1); }).then(function(val) { console.log(val); return 2; }).then(function(val) { console.log(val); return 3; }).then(function(val) { console.log(val); return new Promise(function(resolve,reject) { //异步操作些这里 resolve(4); }); }).then(function(val) { console.log(val); return 5; }).then(function(val) { console.log(val); });
catch方法:
catch方法和失敗回呼時一樣的, 如果上一個非同步函數 拋出了錯誤了,錯誤會被捕獲, 並執行 catch方法或失敗回呼;
var promise = new Promise(function(resolve , reject) { resolve(); //执行成功回调; }); console.log(0); promise.then(function(val) { console.log("成功"); throw new Error("heheda"); }).catch(function(e) { console.log(e); }).then(function() { console.log("继续执行"); });
Promise中的錯誤是會一層層傳遞的, 如果錯誤沒有沒有被捕獲, 會一直傳遞給下一個promise對象, 直到被捕獲為止, 然後繼續往下執行:
new Promise(function(resolve , reject) { resolve(1); }).then(function(val) { console.log(val); return new Promise(function(resolve , reject) { throw new Error("err"); }); }).then(function(val) { console.log(val); return new Promise(function(resolve , reject) { resolve(3); }); }).then(function(val) { console.log(val); return new Promise(function(resolve , reject) { resolve(4); }); }).then(function(val) { console.log(val); }).catch(function(err) { console.log(err); }).then(function() { console.log("继续执行") })
建構子Promise的四個方法:
建構子Promise有四個方法, Promise .all, Promise.race, Promise.reject, Promise.resolve:
Promise.all(iterable)
返回一個promise對象,當iterable參數裡所有的promise都被解決後,該promise也會被解決
要注意all方法是Promise函數的方法,不是實例的方法,參數是數組, 數組裡面全是Promise的實例 :
var p0 = new Promise(function(resolve) { setTimeout(function() { resolve(0) },1000); }) var p1 = new Promise(function(resolve) { setTimeout(function() { resolve(1) },2000); }) var p2 = new Promise(function(resolve) { setTimeout(function() { resolve(2) },3000); }) Promise.all([p0,p1,p2]).then(function(arr) { console.log(arr) })
Promise.race(iterable)
當iterable參數裡的任一個子promise被成功或失敗後,父promise馬上也會以子promise的成功傳回值或失敗詳情作為參數呼叫父promise綁定的對應句柄,並傳回該promise物件。
Promise.reject(reason)
#呼叫Promise的rejected句柄,並傳回這個Promise物件。
Promise.resolve(value)
#用成功值value解決一個Promise物件。如果該value為可繼續的(thenable,即帶有then方法),則傳回的Promise物件會「跟隨」這個value,採用這個value的最終狀態;否則的話傳回值會用這個value滿足(fullfil)傳回的Promise對象。
官方的範例:
<html> <head> <meta charset="utf-8"> </head> <body> <p id="log"></p> <script> 'use strict'; var promiseCount = 0; function testPromise() { var thisPromiseCount = ++promiseCount; var log = document.getElementById('log'); log.insertAdjacentHTML('beforeend', thisPromiseCount + ') 开始(同步代码开始)<br/>'); // 我们创建一个新的promise: 然后用'result'字符串解决这个promise (3秒后) var p1 = new Promise(function (resolve, reject) { // 解决函数带着解决(resolve)或拒绝(reject)promise的能力被执行 log.insertAdjacentHTML('beforeend', thisPromiseCount + ') Promise开始(异步代码开始)<br/>'); // 这只是个创建异步解决的示例 window.setTimeout(function () { // 我们满足(fullfil)了这个promise! resolve(thisPromiseCount) }, Math.random() * 2000 + 1000); }); // 定义当promise被满足时应做什么 p1.then(function (val) { // 输出一段信息和一个值 log.insertAdjacentHTML('beforeend', val + ') Promise被满足了(异步代码结束)<br/>'); }); log.insertAdjacentHTML('beforeend', thisPromiseCount + ') 建立了Promise(同步代码结束)<br/><br/>'); } testPromise(); </script> </body> </html>
既然有了Promise , 我們就可以把封裝XMLHttpRequest封裝成GET方法,方便使用:
function get(url) { // Return a new promise. return new Promise(function(resolve, reject) { // Do the usual XHR stuff var req = new XMLHttpRequest(); req.open('GET', url); req.onload = function() { // This is called even on 404 etc // so check the status if (req.status == 200) { // Resolve the promise with the response text resolve(req.response); } else { // Otherwise reject with the status text // which will hopefully be a meaningful error reject(Error(req.statusText)); } }; // Handle network errors req.onerror = function() { reject(Error("Network Error")); }; // Make the request req.send(); }); }
然後使用:
get('story.json').then(function(response) { console.log("Success!", response); }, function(error) { console.error("Failed!", error); });
假資料的位址可以自己設置, 可以透過控制台請求, 注意跨域的問題;
封裝XMLHttpRequest成Promise非同步載入圖片的案例:http: //www.php.cn/
其他:
以上只是Promise的一些基礎知識, 還有一些其他的知識點, 因為能力有限不一一介紹了(Promise.resolve的不同參數, 與Generator一起使用, Promise的附加方法, 等等等等);
把Promise的運行流程畫出來, 對Promise的理解會好一點, Promise還是比較繞的
瀏覽器支援情況:
#Chrome 32, Opera 1,Firefox 29, Safari 8 ,Microsoft Edge, 這些瀏覽器以上都預設支援;
以上就是ES6新功能:JavaScript中內建的延遲物件Promise 程式碼詳細介紹的內容,更多相關內容請關注PHP中文網(www.php.cn)!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

如何使用WebSocket和JavaScript實現線上語音辨識系統引言:隨著科技的不斷發展,語音辨識技術已成為了人工智慧領域的重要組成部分。而基於WebSocket和JavaScript實現的線上語音辨識系統,具備了低延遲、即時性和跨平台的特點,成為了廣泛應用的解決方案。本文將介紹如何使用WebSocket和JavaScript來實現線上語音辨識系

WebSocket與JavaScript:實現即時監控系統的關鍵技術引言:隨著互聯網技術的快速發展,即時監控系統在各個領域中得到了廣泛的應用。而實現即時監控的關鍵技術之一就是WebSocket與JavaScript的結合使用。本文將介紹WebSocket與JavaScript在即時監控系統中的應用,並給出程式碼範例,詳細解釋其實作原理。一、WebSocket技

如何利用JavaScript和WebSocket實現即時線上點餐系統介紹:隨著網路的普及和技術的進步,越來越多的餐廳開始提供線上點餐服務。為了實現即時線上點餐系統,我們可以利用JavaScript和WebSocket技術。 WebSocket是一種基於TCP協定的全雙工通訊協議,可實現客戶端與伺服器的即時雙向通訊。在即時線上點餐系統中,當使用者選擇菜餚並下訂單

如何使用WebSocket和JavaScript實現線上預約系統在當今數位化的時代,越來越多的業務和服務都需要提供線上預約功能。而實現一個高效、即時的線上預約系統是至關重要的。本文將介紹如何使用WebSocket和JavaScript來實作一個線上預約系統,並提供具體的程式碼範例。一、什麼是WebSocketWebSocket是一種在單一TCP連線上進行全雙工

在日常生活中,我們常常會遇到承諾與兌現之間的問題。無論是在個人關係中,或是在商業交易中,承諾的兌現都是建立信任的關鍵。然而,承諾的利與弊也常常會引起爭議。本文將探討承諾的利與弊,並給予一些建議,如何做到言出必行。承諾的利是顯而易見的。首先,承諾可以建立信任。當一個人信守承諾時,他會讓別人相信自己是個可信賴的人。信任是人與人之間建立的紐帶,它可以讓人們更加

JavaScript和WebSocket:打造高效的即時天氣預報系統引言:如今,天氣預報的準確性對於日常生活以及決策制定具有重要意義。隨著技術的發展,我們可以透過即時獲取天氣數據來提供更準確可靠的天氣預報。在本文中,我們將學習如何使用JavaScript和WebSocket技術,來建立一個高效的即時天氣預報系統。本文將透過具體的程式碼範例來展示實現的過程。 We

JavaScript教學:如何取得HTTP狀態碼,需要具體程式碼範例前言:在Web開發中,經常會涉及到與伺服器進行資料互動的場景。在與伺服器進行通訊時,我們經常需要取得傳回的HTTP狀態碼來判斷操作是否成功,並根據不同的狀態碼來進行對應的處理。本篇文章將教你如何使用JavaScript來取得HTTP狀態碼,並提供一些實用的程式碼範例。使用XMLHttpRequest

Promise.resolve()詳解,需要具體程式碼範例Promise是JavaScript中一種用來處理非同步操作的機制。在實際開發中,常常需要處理一些需要依序執行的非同步任務,而Promise.resolve()方法就是用來傳回一個已經Fulfilled狀態的Promise物件。 Promise.resolve()是Promise類別的靜態方法,它接受一個
