Javascript如何理解全國甲卷高考作文
前言
2022年全國甲卷高考語文作文已然出爐,筆者看到后居然想起了這個(gè)表情包
好家伙,還好我提前成為了一名默默在卷大學(xué)生,不然以這篇作文的難度足以讓我招架不住。話不多說,咱們來看看百度作文給出的題目解析:
這是一則材料作文。材料由兩個(gè)部分組成,第一部分是現(xiàn)象,介紹傳統(tǒng)文化經(jīng)典《紅樓夢(mèng)》中眾人給匾額題名三種不同的方式;第二部分是對(duì)上述三種題名方法的評(píng)價(jià),暗示了對(duì)傳統(tǒng)文化的繼承、發(fā)展與創(chuàng)新。“直接移用”,“借鑒化用”,“根據(jù)情境獨(dú)創(chuàng)”,也就是直接學(xué)習(xí)、借鑒、創(chuàng)新三步走。在此基礎(chǔ)上,由文學(xué)作品中的情節(jié)內(nèi)涵拓展到更廣泛的領(lǐng)域,引發(fā)學(xué)生深入思考。
透過這個(gè)解析我們可以看到這則材料作文由兩個(gè)部分構(gòu)成,第一部分是現(xiàn)象,具體是指《紅樓夢(mèng)》中眾人給匾額題名三種不同的方式;第二部分則是對(duì)上述三種題名方法的評(píng)價(jià)。由于筆者水平有限,所以決定在直接引用、借鑒化用、根據(jù)情境獨(dú)創(chuàng)
這三個(gè)題眼上下手,那么它們所對(duì)應(yīng)的順序也自然是學(xué)習(xí)、借鑒、創(chuàng)新
,通過一步一步的摸索,最終達(dá)到好的理想狀況,而又經(jīng)過對(duì)題目解析的反復(fù)揣摩,筆者腦中忽然靈光一現(xiàn),我能不能以JavaScript中處理并發(fā)請(qǐng)求的幾種方式為素材來試著寫寫這篇作文呢?
因筆者水平有限,本篇文章所理解內(nèi)容僅為個(gè)人觀點(diǎn)。我會(huì)嘗試將“翼然”、“瀉玉”、“沁芳”分為三個(gè)階段,每個(gè)階段都是對(duì)前一個(gè)階段的升華,通過一步一步的摸索、前進(jìn),最終達(dá)到“沁芳”的理想層面。
我之前的介紹過關(guān)于異步任務(wù)的題目雖然也不少,但究竟應(yīng)該如何優(yōu)雅的處理并發(fā)請(qǐng)求呢?要知道在ES6
之前,我們發(fā)送依賴請(qǐng)求大概如下所示:
場(chǎng)景:根據(jù)用戶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) }) }) })
由上述代碼可知,這種寫法通常會(huì)飽受回調(diào)地獄的“折磨”,尤其是當(dāng)依賴的請(qǐng)求變的越來越多時(shí),我們的“屎山”也便一發(fā)不可收拾了。當(dāng)Promise
問世之后,我們來看看又該如何優(yōu)化,而這一優(yōu)化是不是也代表著“翼然”向“瀉玉”所作出的轉(zhuǎn)變呢?
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) })
由此可見,當(dāng)應(yīng)用了Promise
之后,這座“屎山”也隨之被鏟平了。如果說then
的鏈?zhǔn)秸{(diào)用足以磨平請(qǐng)求代碼的“屎山”,那么我們今天用一個(gè)需求,來展現(xiàn)async
降維打擊的能力之強(qiáng),下面我們開始逐漸處理并發(fā)請(qǐng)求,也一道解開“翼然”、“瀉玉”、“沁芳”之間的關(guān)系
回顧
Promise
Promise
的特點(diǎn)是同步執(zhí)行代碼,且在未決議之前擁有三種狀態(tài):初始化狀態(tài)為pending
、成功狀態(tài)為resolve
、失敗狀態(tài)為rejected
。在未調(diào)用resolve
以及rejected
之前,狀態(tài)始終保持為pending
,調(diào)用resolve
和rejected
后狀態(tài)分別為成功/失敗,要注意的是狀態(tài)一旦確定,不可更改。每個(gè)Promise對(duì)象都會(huì)返回一個(gè)then
方法,這個(gè)then
方法會(huì)在Promise
對(duì)象成功/失敗時(shí)如期調(diào)用,因?yàn)檫@是Promise
所作出的承諾,例如:
var p = new Promise((resolve, rejected) => { // 1秒鐘之后調(diào)用resolve,將初始化狀態(tài)改為成功狀態(tài) // 注意,在此1秒鐘之前,p的狀態(tài)始終為初始化狀態(tài),因?yàn)镻romise尚未作出決議 setTimeout(resolve, 1000) }) // then方法會(huì)在約1秒鐘后執(zhí)行 p.then(data => console.log(data))
Promise.all
all
方法接收一個(gè)具有iterator
接口的數(shù)據(jù),例如數(shù)組。要注意的是這個(gè)數(shù)組中的每一個(gè)成員都必須是一個(gè)Promise
對(duì)象,all
方法會(huì)返回這些Promise
對(duì)象成功或失敗的值,例如:
var p = async () => await new Promise(r => setTimeout(r, 1000)) var f = Promise.all([p, p]) // then方法會(huì)在約1秒鐘后執(zhí)行 p().then(data => console.log(data))
async
async
函數(shù)始終會(huì)返回一個(gè)Promise
對(duì)象,這個(gè)Promise
對(duì)象的狀態(tài)取決于async
函數(shù)的返回值。await
關(guān)鍵字的職責(zé)就是異步求值,通常后面會(huì)是一個(gè)Promise
對(duì)象,await
關(guān)鍵字會(huì)“自動(dòng)”幫我們then
這個(gè)Promise
對(duì)象,然后拿到數(shù)據(jù)進(jìn)行返回。注意,只有當(dāng)await
后面的這個(gè)Promise
對(duì)象決議了,async
函數(shù)才會(huì)繼續(xù)往下執(zhí)行,否則交出線程轉(zhuǎn)而執(zhí)行其它任務(wù),例如:
// f會(huì)在約1秒鐘后決議 var f = async () => await new Promise(r => setTimeout(r, 1000)) // then方法會(huì)在約1秒鐘后執(zhí)行 f().then(data => console.log(data))
需求
回顧完成,接下來我們通過這個(gè)需求來解開“翼然”、“瀉玉”、“沁芳”之間的關(guān)系。比如我有一個(gè)裝有一百個(gè)書本id
的數(shù)組,我需要獲取每個(gè)書本的詳細(xì)內(nèi)容,雖然是一百本書,但由于只有一個(gè)接口,所以需要重復(fù)調(diào)用,只不過在調(diào)用時(shí)每次的入?yún)d均不同而已
實(shí)現(xiàn)
準(zhǔn)備準(zhǔn)備
數(shù)據(jù)
books中存儲(chǔ)著每個(gè)書本的id,我們需要通過這些枯燥無味的id來拿到每個(gè)書本所對(duì)應(yīng)的信息
var books = [ {id: "0000"}, {id: "1111"}, {id: "2222"}, {id: "3333"}, // more... ]
封裝請(qǐng)求
我們先封裝一個(gè)request
方法,用于請(qǐng)求單個(gè)書本id所對(duì)應(yīng)的信息。因?yàn)闆]有這么合適的接口來供我們練習(xí),所以此處暫時(shí)決定使用setTimeout
來代替請(qǐng)求區(qū)域
// request方法會(huì)在約1秒鐘后“請(qǐng)求成功” var request = id => new Promise(resolve => setTimeout(resolve, 1000))
原生
通過xhr
封裝一個(gè)請(qǐng)求,要注意的是這里的請(qǐng)求函數(shù)requestJs
并未用到Promise
對(duì)象,而是使用了原汁原味的回調(diào)模式,因?yàn)樵?code>ES6之前Promise
尚未面世,這也正對(duì)應(yīng)了最開始的階段——“翼然”
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) } } } } // 通過定時(shí)器來模擬請(qǐng)求 var requestJsPolyill = (id, callback) => { setTimeout(() => { callback(id) }, 1000) } var judge = data => { info.push(data) if (books.length === info.length) { console.log('請(qǐng)求到的數(shù)據(jù):', info) } } books.forEach(v => requestJsPolyill(v.id, judge))
Promise
每請(qǐng)求到一個(gè)書本的信息就追加到info
數(shù)組中,每次追加后,來判斷books
與info
的長度是否相同,如果相同,則代表所有書本信息均已請(qǐng)求完畢,如果不同則代表尚有書本信息未請(qǐng)求成功,我們正是通過這種方式來處理并發(fā)請(qǐng)求,可以看到的是Promise
這種方式正是對(duì)原生JS的一種化用,或者說是一種更好的改變,所以也就符合了“瀉玉”這一階段
// 存儲(chǔ)獲取到的書本信息 var info = [] var f = new Promise(resolve => { books.forEach(v => { // 根據(jù)books中每個(gè)id進(jìn)行請(qǐng)求 request(v.id).then(() => { // 每請(qǐng)求到一個(gè)書本信息都會(huì)放在info中 info.push(v.id) // 當(dāng)請(qǐng)求完的信息數(shù)量與原始書本的數(shù)量對(duì)應(yīng)起來時(shí),則代表全部請(qǐng)求完成 if (books.length === info.length) { resolve(info) } }) }) }) // 獲取完全部書本信息后執(zhí)行then方法 f.then(data => { console.log('請(qǐng)求到的數(shù)據(jù):', data) })
async
由于map
方法會(huì)返回一個(gè)新數(shù)組,所以此處通過map
來對(duì)books
中的每一個(gè)書本id都加工成一個(gè)請(qǐng)求,通過request
來完成這個(gè)請(qǐng)求,而request
又會(huì)返回一個(gè)Promise
對(duì)象,這樣一來,返回的這個(gè)新數(shù)組中的每個(gè)成員就都是一個(gè)Promise
對(duì)象,而Promise.all
方法在接收到這個(gè)新數(shù)組后,會(huì)并發(fā)執(zhí)行所有Promise
對(duì)象,等到所有Promise
對(duì)象都決議后,then
方法才會(huì)被調(diào)用。使用async
來完成這個(gè)需求,無論是代碼簡(jiǎn)潔程度還是可讀性,都大大的超越了“翼然”和“瀉玉”這兩個(gè)階段,也可以說這正是“沁芳”的獨(dú)特所在
// 當(dāng)新數(shù)組中的所有Promise全部決議后,then會(huì)被如期調(diào)用 var f = Promise.all(books.map(async v => await request(v.id))) f.then(data => { console.log('請(qǐng)求到的數(shù)據(jù):', data) })
文末
我們分別使用了三種方式來處理并發(fā)請(qǐng)求,期間我們也闡述了它們各自的特點(diǎn),而這也正好對(duì)應(yīng)了文章開頭所提到的材料作文兩個(gè)部分:眾人題匾的三種方式以及對(duì)三種方式的評(píng)價(jià)。在Promise未面世之前,我們通常使用原生JavaScript
來處理請(qǐng)求,常用的手法也自然是使用回調(diào)地獄,這一階段算是處于初始階段,也就正好對(duì)應(yīng)了“翼然”這一層面,而通過對(duì)原生JavaScript請(qǐng)求方式的改善,將多層嵌套逐漸扁平化來優(yōu)化代碼,通過這一點(diǎn)Promise
也正符合了“瀉玉”這一階段,看到async
的實(shí)現(xiàn)方式才明白原來代碼還可以如此優(yōu)雅,比如可讀性、擴(kuò)展性都要比前者強(qiáng)出不少,可能這大概就是創(chuàng)新的魅力所在了吧。無論是“翼然”還是“瀉玉”,距離我們理想的代碼層面尚有些許不足,而正是這些不足的存在,我們才能一步一步的創(chuàng)新、前進(jìn),最終達(dá)到“沁芳”的理想層面
到此這篇關(guān)于Javascript如何理解全國甲卷高考作文的文章就介紹到這了,更多相關(guān)js理解全國甲卷高考作文內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
全面解讀TypeScript和JavaScript的區(qū)別
TypeScript和JavaScript是目前項(xiàng)目開發(fā)中較為流行的兩種腳本語言, TypeScript是JavaScript的一個(gè)超集,JavaScript是一種輕量級(jí)的解釋性腳本語言,本文主要介紹了兩者區(qū)別,感興趣的可以了解一下2023-09-09JS如何實(shí)現(xiàn)頁面截屏功能實(shí)例代碼
這篇文章主要給大家介紹了關(guān)于JS如何實(shí)現(xiàn)頁面截屏功能的相關(guān)資料,文中主要利用了html2canvas和canvas繪制兩個(gè)方法來實(shí)現(xiàn),需要的朋友可以參考下2021-06-06JS獲取指定時(shí)間的時(shí)間戳的方法匯總(最新整理收藏版)
在JavaScript中,可以使用Date.parse()或new Date()來獲取指定時(shí)間的時(shí)間戳,本文給大家分享JS獲取指定時(shí)間的時(shí)間戳的方法,感興趣的朋友一起看看吧2024-01-01PHP自動(dòng)加載autoload和命名空間的應(yīng)用小結(jié)
PHP的自動(dòng)加載就是我們加載實(shí)例化類的時(shí)候,不需要手動(dòng)去寫require來導(dǎo)入這個(gè)class.php文件,程序自動(dòng)幫我們加載導(dǎo)入進(jìn)來這.篇文章主要介紹了PHP自動(dòng)加載autoload和命名空的應(yīng)用,需要的朋友可以參考下2017-12-12js實(shí)現(xiàn)導(dǎo)入導(dǎo)出功能實(shí)例代碼(FileSave.js)
這篇文章主要給大家介紹了關(guān)于js實(shí)現(xiàn)導(dǎo)入導(dǎo)出功能(FileSave.js)的相關(guān)資料,FileSaver.js是在客戶端保存文件的解決方案,非常適合在客戶端上生成文件的Web應(yīng)用,需要的朋友可以參考下2023-11-11JavaScript switch case 的用法實(shí)例[范圍]
JavaScript switch case 的用法實(shí)例,大家可以參考下。2009-09-09省市區(qū)三級(jí)聯(lián)動(dòng)下拉框菜單javascript版
這篇文章主要給大家介紹了javascript實(shí)現(xiàn)省市區(qū)三級(jí)聯(lián)動(dòng)下拉框菜單,有需要的朋友可以參考下2015-08-08