實例解析ES6 Promise的原理與使用
1. Promise 之前
1.1 回调函数
回调函数:把函数A当作参数传递给另一个函数B调用,那么A就是回调函数。【推荐:JavaScript视频教程】
一些例子
具名回调
function 你有几只狗(fn){ fn('一只狗') }function 数狗(数量){ console.log(数量) } 你有几只狗(数狗) // 一只狗
匿名回调
function 你有几只狗(fn){ fn('一只狗') } 你有几只狗(function(数量){console.log(数量) }) // 一只狗
常见的例子
jQuery中使用回调函数,这里用的是匿名回调的方式
$("#btn").click(function(){ console.log('点到我了') })
1.2 回调地狱(回调缺点1)
回调地狱:指的是回调嵌套过多的情况,导致代码很难被看懂。
let info = []function 你有几只狗(fn){ fn('一只狗') }function 你有几只猫(fn){ fn('一只猫') }function 知道了(数量,callback){ info.push(数量) console.log(info) if(callback){ callback() } }// 开始调用 如果比这再多几层,就不容易看懂了你有几只狗(function(狗数){ console.log(狗数) 知道了(狗数, function(){ 你有几只猫(function(猫数){ console.log(猫数) 知道了(猫数) }) }) })
1.3 不使用Promise,如何解决
利用具名函数代替匿名函数
let info = []function 你有几只狗(fn){ fn('一只狗') }function 你有几只猫(fn){ fn('一只猫') }function 知道了(数量,callback){ info.push(数量) console.log(info) if(callback){ callback() } }function 告诉你猫的个数(猫数){ console.log(猫数) 知道了(猫数) }function 继续数(){ 你有几只猫(告诉你猫的个数) }function 告诉你狗的个数(狗数){ console.log(狗数) 知道了(狗数, 继续数) } 你有几只狗(告诉你狗的个数) // 好像也没好到哪去。。。
1.4 回调方式各不相同,需要单独记忆(回调缺点2)
readFile('C:\\1.txt',function (error, data) { // node.js 读取文件方法中的回调 if(error) { console.log('成功') console.log(data.toString()) } else { console.log('读取文件失败') } }) $.ajax({ // jQuery中ajax方法中的回调 url:'/2.txt' success: function(response) { console.log('成功') }, error: function(){ console.log('失败') } })
2. Promise 的目的
Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。它由社区最早提出和实现,ES6 将其写进了语言标准,统一了用法,原生提供了Promise对象。
3. Promise 的原理
3.1 实现原理
ES6 规定,Promise对象是一个构造函数,用来生成Promise实例。通过在函数内部return 一个 Promise对象的实例,这样就可以使用Promise的属性和方法进行下一步操作了。
function 函数名(){ return new Promise(function(resolve, reject) { // ... some code if (/* 异步操作成功 */){ resolve(value); // 异步操作成功时调用,把结果作为参数传递出去 } else { reject(error); // 异步失败时调用,把错误作为参数传递出去 } }) }
3.2 调用逻辑
S1和E1两个都没有报错,执行S2(resolve执行,系统认为搞定了,没报错)
S1和E1任何一个有报错,执行E2(reject执行,系统认为没搞定,报错了)
4. Promise 的使用
4.1 Promise 的属性与方法
属性
Promise.prototype 表示 Promise 构造器的原型
方法
Promise.prototype.then()
返回一个 Promise 。它最多需要有两个参数:Promise 的成功和失败情况的回调函数。
Promise.prototype.catch()
返回一个Promise,并且处理拒绝的情况。等价于Promise.prototype.then(undefined, onRejected)
Promise.prototype.finally()
finally() 方法返回一个Promise,在执行then()和catch()后,都会执行finally指定的回调函数。避免同样的语句需要在then()和catch()中各写一次的情况。
Promise.all(iterable)
返回一个 Promise 实例,iterable参数内所有的 promise 都resolved后,才回调完成resolve。
Promise.race(iterable)
返回一个 promise ,并伴随着 promise对象解决的返回值或拒绝的错误原因, 只要 iterable 中有一个 promise 对象”解决(resolve)”或”拒绝(reject)”。
Promise.resolve()
返回一个以给定值解析后的Promise对象。但如果这个值是个thenable(即带有then方法),返回的promise会“跟随”这个thenable的对象,采用它的最终状态(指resolved/rejected/pending/settled);如果传入的value本身就是promise对象,则该对象作为Promise.resolve方法的返回值返回;否则以该值为成功状态返回promise对象。
Promise.reject()
返回一个带有拒绝原因reason参数的Promise对象。
4.2 将回调地狱中的例子,改写为Promise的形式
可以看到使用 Promise后,逻辑变得非常直观
写得更完整一些
Promise套Promise时,也就是Promise链的时候——注意信息的传递
一个失败的例子,当我们使用Promise链的时候,如果每一步都需要上一步的数据时,就需要传参,成功通过resolve传参,失败通过reject传参,如果忘记传参,就得不到想要的结果。
resolve把成功的数据返回给下一个回调
reject把失败的数据返回给下一个回调。
给这里的resolve传一个参
改成失败的例子
先不给reject传参,如果失败的话,下一个回调拿不到数据
给 reject传参
我们可以看到,即使是走的失败回调,下一个成功回调还是执行了,由于 不知道() 默认返回undefined, 相当于失败已经处理了,在成功和失败都被处理的情况下,下一个回调会执行的。
改成符合预期的,即失败不调用。
失败不调用的简写形式
上述情况执行后 .then(除了狗呢)里面的成功回调没有执行,我们增加一个失败回调看看
同样也可以返回 resolve,让后面成功回调可以执行
4.3 应用
加载图片
将图片的加载写成一个Promise,一旦加载完成,Promise的状态就发生变化。
const preloadImage = function (path) { return new Promise(function (resolve, reject) { const image = new Image(); image.onload = resolve; image.onerror = reject; image.src = path; }); };
Generator 函数与 Promise 的结合(详情见参考链接,阮一峰的教程)
5. 干掉Promise中的回调
5.1 await
成功的情况
失败的情况
利用 try catch
await 配合 try catch使用,比较完整
6. 总结
能利用Promise对象,把普通函数改成返回Promise的形式,解决回调地狱的问题。
明白Promise的成功失败调用逻辑,可以灵活的进行调整。
理解核心知识,先用起来,慢慢整合吸收知识。
以上是實例解析ES6 Promise的原理與使用的詳細內容。更多資訊請關注PHP中文網其他相關文章!

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

async是es7的。 async和await是ES7中新增內容,是對於非同步操作的解決方案;async/await可以說是co模組和生成器函數的語法糖,用更清晰的語意解決js非同步程式碼。 async顧名思義是「非同步」的意思,async用於聲明一個函數是異步的;async和await有一個嚴格規定,兩者都離不開對方,且await只能寫在async函數中。

為了瀏覽器相容。 ES6作為JS的新規範,加入了許多新的語法和API,但現代瀏覽器對ES6新特性支援不高,所以需將ES6程式碼轉換為ES5程式碼。在微信web開發者工具中,會預設使用babel將開發者ES6語法程式碼轉換為三端都能很好支援的ES5的程式碼,幫助開發者解決環境不同所帶來的開發問題;只需要在專案中配置勾選好「ES6轉ES5」選項即可。

es5中可以利用for語句和indexOf()函數來實現數組去重,語法“for(i=0;i<數組長度;i++){a=newArr.indexOf(arr[i]);if(a== -1){...}}」。在es6中可以利用擴充運算子、Array.from()和Set來去重;需要先將陣列轉為Set物件來去重,然後利用擴充運算子或Array.from()函數來將Set物件轉回數組即可。

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

Vue是一款受歡迎的前端框架,在開發應用時經常會遇到各種各樣的錯誤和問題。其中,Uncaught(inpromise)TypeError是常見的一種錯誤型別。在本篇文章中,我們將探討它的產生原因和解決方法。什麼是Uncaught(inpromise)TypeError? Uncaught(inpromise)TypeError錯誤通常出現在

在es6中,暫時性死區是語法錯誤,是指let和const命令使區塊形成封閉的作用域。在程式碼區塊內,使用let/const指令宣告變數之前,變數都是不可用的,在變數宣告之前屬於該變數的「死區」;這在語法上,稱為「暫時性死區」。 ES6規定暫時性死區和let、const語句不出現變量提升,主要是為了減少運行時錯誤,防止在變量聲明前就使用這個變量,從而導致意料之外的行為。

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

在es6中,可以利用array物件的length屬性來判斷數組裡總共有多少項,即取得數組中元素的個數;該屬性可傳回數組中元素的數組,只需要使用「array.length」語句即可傳回表示數組物件的元素個數的數值,也就是長度值。
