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)!

在es6中,可以利用“Array.isArray()”方法判断对象是否为数组,若判断的对象是数组,返回的结果是true,若判断对象不是数组,返回的结果是false,语法为“Array.isArray(需要检测的js对象)”。

es6中遍历跟迭代的区别是:遍历强调的是要把整个数据依次全部取出来,是访问数据结构的所有元素;而迭代虽然也是依次取出数据,但是并不保证取多少,也不保证把所有的数据取完,是遍历的一种形式。

在es6中,可用Object对象的is()方法来判断两个对象是否相等,该方法检测两个变量的值是否为同一个值,判断两个对象的引用地址是否一致,语法“Object.is(对象1,对象2)”;该方法会返回布尔值,若返回true则表示两个对象相等。

转换方法:1、利用“+”给数字拼接一个空字符,语法“数字+""”;2、使用String(),可把对象的值转换为字符串,语法“String(数字对象)”;3、用toString(),可返回数字的字符串表示,语法“数字.toString()”。

在es6中,assign用于对象的合并,可以将源对象的所有可枚举属性复制到目标对象;若目标对象与源对象有同名属性,或多个源对象有同名属性,则后面的属性会覆盖前面的属性,语法为“Object.assign(...)”

改变方法:1、利用splice()方法修改,该方法可以直接修改原数组的内容,语法为“数组.splice(开始位置,修改个数,修改后的值)”;2、利用下标访问数组元素,并重新赋值来修改数组数据,语法为“数组[下标值]=修改后的值;”。

sort排序是es6中的;sort排序是es6中用于对数组的元素进行排序的方法,该方法默认不传参,按照字符编码顺序进行排序,排序顺序可以是字母或数字,并按升序或降序,语法为“array.sort(callback(a,b))”。

在es6中,import as用于将若干export导出的内容组合成一个对象返回;ES6的模块化分为导出与导入两个模块,该方法能够将所有的导出内容包裹到指定对象中,语法为“import * as 对象 from ...”。


熱AI工具

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

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

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

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

SublimeText3 Linux新版
SublimeText3 Linux最新版

SecLists
SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。

WebStorm Mac版
好用的JavaScript開發工具

SublimeText3 英文版
推薦:為Win版本,支援程式碼提示!