您好,登錄后才能下訂單哦!
這篇文章主要介紹“Javascript怎么理解全國甲卷高考作文”的相關知識,小編通過實際案例向大家展示操作過程,操作方法簡單快捷,實用性強,希望這篇“Javascript怎么理解全國甲卷高考作文”文章能幫助大家解決問題。
場景:根據用戶id(001),獲取到用戶姓名后,再獲取用戶性別,再獲取用戶年齡
function getUserName(id, callback) { setTimeout(function () { callback('001姓名為鯊魚辣椒') }, 1000) } function getUserSex(id, callback) { setTimeout(function () { callback('001性別為男') }, 1000) } function getUserAge(id, callback) { setTimeout(function () { callback('001年齡為5') }, 1000) } // 開始套娃 getUserName('001', function (name) { console.log(name) getUserSex('001', function (sex) { console.log(sex) getUserAge('001', function (age) { console.log(age) }) }) })
由上述代碼可知,這種寫法通常會飽受回調地獄的“折磨”,尤其是當依賴的請求變的越來越多時,我們的“屎山”也便一發不可收拾了。當Promise
問世之后,我們來看看又該如何優化,而這一優化是不是也代表著“翼然”向“瀉玉”所作出的轉變呢?
function getUserName(id) { return new Promise(function (resolve) { setTimeout(function () { resolve('001姓名為鯊魚辣椒') }, 1000) }) } function getUserSex(id) { return new Promise(function (resolve) { setTimeout(function () { resolve('001性別為男') }, 1000) }) } function getUserAge(id) { return new Promise(function (resolve) { setTimeout(function () { resolve('001年齡為5') }, 1000) }) } // 禁止套娃,一切都開始扁平了起來 getUserName('001').then(function (data) { console.log(data) return getUserSex('001') }).then(function (data) { console.log(data) return getUserAge('001') }).then(function (data) { console.log(data) })
由此可見,當應用了Promise
之后,這座“屎山”也隨之被鏟平了。如果說then
的鏈式調用足以磨平請求代碼的“屎山”,那么我們今天用一個需求,來展現async
降維打擊的能力之強,下面我們開始逐漸處理并發請求,也一道解開“翼然”、“瀉玉”、“沁芳”之間的關系
Promise
的特點是同步執行代碼,且在未決議之前擁有三種狀態:初始化狀態為pending
、成功狀態為resolve
、失敗狀態為rejected
。在未調用resolve
以及rejected
之前,狀態始終保持為pending
,調用resolve
和rejected
后狀態分別為成功/失敗,要注意的是狀態一旦確定,不可更改。每個Promise對象都會返回一個then
方法,這個then
方法會在Promise
對象成功/失敗時如期調用,因為這是Promise
所作出的承諾,例如:
var p = new Promise((resolve, rejected) => { // 1秒鐘之后調用resolve,將初始化狀態改為成功狀態 // 注意,在此1秒鐘之前,p的狀態始終為初始化狀態,因為Promise尚未作出決議 setTimeout(resolve, 1000) }) // then方法會在約1秒鐘后執行 p.then(data => console.log(data))
all
方法接收一個具有iterator
接口的數據,例如數組。要注意的是這個數組中的每一個成員都必須是一個Promise
對象,all
方法會返回這些Promise
對象成功或失敗的值,例如:
var p = async () => await new Promise(r => setTimeout(r, 1000)) var f = Promise.all([p, p]) // then方法會在約1秒鐘后執行 p().then(data => console.log(data))
async
函數始終會返回一個Promise
對象,這個Promise
對象的狀態取決于async
函數的返回值。await
關鍵字的職責就是異步求值,通常后面會是一個Promise
對象,await
關鍵字會“自動”幫我們then
這個Promise
對象,然后拿到數據進行返回。注意,只有當await
后面的這個Promise
對象決議了,async
函數才會繼續往下執行,否則交出線程轉而執行其它任務,例如:
// f會在約1秒鐘后決議 var f = async () => await new Promise(r => setTimeout(r, 1000)) // then方法會在約1秒鐘后執行 f().then(data => console.log(data))
回顧完成,接下來我們通過這個需求來解開“翼然”、“瀉玉”、“沁芳”之間的關系。比如我有一個裝有一百個書本id
的數組,我需要獲取每個書本的詳細內容,雖然是一百本書,但由于只有一個接口,所以需要重復調用,只不過在調用時每次的入參id均不同而已
books中存儲著每個書本的id,我們需要通過這些枯燥無味的id來拿到每個書本所對應的信息
var books = [ {id: "0000"}, {id: "1111"}, {id: "2222"}, {id: "3333"}, // more... ]
我們先封裝一個request
方法,用于請求單個書本id所對應的信息。因為沒有這么合適的接口來供我們練習,所以此處暫時決定使用setTimeout
來代替請求區域
// request方法會在約1秒鐘后“請求成功” var request = id => new Promise(resolve => setTimeout(resolve, 1000))
通過xhr
封裝一個請求,要注意的是這里的請求函數requestJs
并未用到Promise
對象,而是使用了原汁原味的回調模式,因為在ES6
之前Promise
尚未面世,這也正對應了最開始的階段——“翼然”
var info = [] var requestJs = (id, callback) => { var xhr = new XMLHttpRequest() open('GET', 'url') xhr.send(null) xhr.onreadyStatechange = function () { if (xhr.readyState == 4) { if (xhr.status >= 200 && xhr.status < 300) { callback(xhr.responseText) } } } } // 通過定時器來模擬請求 var requestJsPolyill = (id, callback) => { setTimeout(() => { callback(id) }, 1000) } var judge = data => { info.push(data) if (books.length === info.length) { console.log('請求到的數據:', info) } } books.forEach(v => requestJsPolyill(v.id, judge))
每請求到一個書本的信息就追加到info
數組中,每次追加后,來判斷books
與info
的長度是否相同,如果相同,則代表所有書本信息均已請求完畢,如果不同則代表尚有書本信息未請求成功,我們正是通過這種方式來處理并發請求,可以看到的是Promise
這種方式正是對原生JS的一種化用,或者說是一種更好的改變,所以也就符合了“瀉玉”這一階段
// 存儲獲取到的書本信息 var info = [] var f = new Promise(resolve => { books.forEach(v => { // 根據books中每個id進行請求 request(v.id).then(() => { // 每請求到一個書本信息都會放在info中 info.push(v.id) // 當請求完的信息數量與原始書本的數量對應起來時,則代表全部請求完成 if (books.length === info.length) { resolve(info) } }) }) }) // 獲取完全部書本信息后執行then方法 f.then(data => { console.log('請求到的數據:', data) })
由于map
方法會返回一個新數組,所以此處通過map
來對books
中的每一個書本id都加工成一個請求,通過request
來完成這個請求,而request
又會返回一個Promise
對象,這樣一來,返回的這個新數組中的每個成員就都是一個Promise
對象,而Promise.all
方法在接收到這個新數組后,會并發執行所有Promise
對象,等到所有Promise
對象都決議后,then
方法才會被調用。使用async
來完成這個需求,無論是代碼簡潔程度還是可讀性,都大大的超越了“翼然”和“瀉玉”這兩個階段,也可以說這正是“沁芳”的獨特所在
// 當新數組中的所有Promise全部決議后,then會被如期調用 var f = Promise.all(books.map(async v => await request(v.id))) f.then(data => { console.log('請求到的數據:', data) })
關于“Javascript怎么理解全國甲卷高考作文”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識,可以關注億速云行業資訊頻道,小編每天都會為大家更新不同的知識點。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。