电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術文章
文章詳情頁

淺談JavaScript中的異步處理

瀏覽:126日期:2023-11-12 14:31:40

整理于互聯網

在 JavaScript 的世界中,所有代碼都是單線程執行的 由于這個“缺陷”,導致 JavaScript 的所有網絡操作,瀏覽器事件,都必須是異步執行。異步執行可以用回調函數實現 異步操作會在將來的某個時間點觸發一個函數調用 主流的異步處理方案主要有:回調函數 (CallBack) 、 Promise 、 Generator 函數、 async/await 。 一、回調函數(CallBack) 這是異步編程最基本的方法 假設我們有一個 getData 方法,用于異步獲取數據,第一個參數為請求的 url 地址,第二個參數是回調函數,如下:

function getData(url, callBack){ // 模擬發送網絡請求 setTimeout(()=> {// 假設 res 就是返回的數據var res = { url: url, data: Math.random()}// 執行回調,將數據作為參數傳遞callBack(res) }, 1000)} 我們預先設定一個場景,假設我們要請求三次服務器,每一次的請求依賴上一次請求的結果,如下:

getData(’/page/1?param=123’, (res1) => { console.log(res1) getData(`/page/2?param=${res1.data}`, (res2) => {console.log(res2)getData(`/page/3?param=${res2.data}`, (res3) => { console.log(res3)}) })})

通過上面的代碼可以看出,第一次請求的 url 地址為: /page/1?param=123 ,返回結果為 res1 。

第二個請求的 url 地址為: /page/2?param=${res1.data} ,依賴第 一次請求的 res1.data ,返回結果為 res2`。

第三次請求的 url 地址為: /page/3?param=${res2.data} ,依賴第二次請求的 res2.data ,返回結果為 res3 。

由于后續請求依賴前一個請求的結果,所以我們只能把下一次請求寫到上一次請求的回調函數內部,這樣就形成了常說的:回調地獄。

二、發布/訂閱

我們假定,存在一個”信號中心”,某個任務執行完成,就向信號中心”發布”( publish )一個信號,其他任務可以向信號中心”訂閱”( subscribe )這個信號,從而知道什么時候自己可以開始執行。這就叫做”發布/訂閱模式”(publish-subscribe pattern),又稱”觀察者模式”(observer pattern)

這個模式有多種實現,下面采用的是Ben Alman的 Tiny Pub/Sub ,這是 jQuery 的一個插件 首先, f2 向”信號中心” jQuery 訂閱” done “信號

jQuery.subscribe('done', f2); f1進行如下改寫

function f1(){setTimeout(function(){// f1的任務代碼jQuery.publish('done');}, 1000);} jQuery.publish('done') 的意思是, f1 執行完成后,向”信號中心 'jQuery 發布 'done' 信號,從而引發f2的執行。 此外,f2完成執行后,也可以取消訂閱( unsubscribe )

jQuery.unsubscribe('done', f2); 這種方法的性質與”事件監聽”類似,但是明顯優于后者。因為我們可以通過查看”消息中心”,了解存在多少信號、每個信號有多少訂閱者,從而監控程序的運行。 三、Promise Promise 是異步編程的一種解決方案,比傳統的解決方案——回調函數和事件——更合理和更強大 所謂 Promise ,簡單說就是一個容器,里面保存著某個未來才會結束的事件(通常是一個異步操作)的結果。從語法上說, Promise 是一個對象,從它可以獲取異步操作的消息。 Promise 提供統一的 API ,各種異步操作都可以用同樣的方法進行處理 簡單說,它的思想是,每一個異步任務返回一個 Promise 對象,該對象有一個 then 方法,允許指定回調函數。 現在我們使用 Promise 重新實現上面的案例,首先,我們要把異步請求數據的方法封裝成 Promise

function getDataAsync(url){ return new Promise((resolve, reject) => {setTimeout(()=> { var res = {url: url,data: Math.random() } resolve(res)}, 1000) })} 那么請求的代碼應該這樣寫

getDataAsync(’/page/1?param=123’) .then(res1=> {console.log(res1)return getDataAsync(`/page/2?param=${res1.data}`) }) .then(res2=> {console.log(res2)return getDataAsync(`/page/3?param=${res2.data}`) }) .then(res3=> {console.log(res3) }) then 方法返回一個新的 Promise 對象, then 方法的鏈式調用避免了 CallBack 回調地獄 但也并不是完美,比如我們要添加很多 then 語句, 每一個 then 還是要寫一個回調。 如果場景再復雜一點,比如后邊的每一個請求依賴前面所有請求的結果,而不僅僅依賴上一次請求的結果,那會更復雜。 為了做的更好, async/await 就應運而生了,來看看使用 async/await 要如何實現 四、async/await

getDataAsync 方法不變,如下

function getDataAsync(url){ return new Promise((resolve, reject) => {setTimeout(()=> { var res = {url: url,data: Math.random() } resolve(res)}, 1000) })} 業務代碼如下

async function getData(){ var res1 = await getDataAsync(’/page/1?param=123’) console.log(res1) var res2 = await getDataAsync(`/page/2?param=${res1.data}`) console.log(res2) var res3 = await getDataAsync(`/page/2?param=${res2.data}`) console.log(res3)} 可以看到使用 asyncawait 就像寫同步代碼一樣 對比 Promise 感覺怎么樣?是不是非常清晰,但是 async/await 是基于 Promise 的,因為使用 async 修飾的方法最終返回一個 Promise , 實際上, async/await 可以看做是使用 Generator 函數處理異步的語法糖,我們來看看如何使用 Generator 函數處理異步 五、Generator 首先異步函數依然是

function getDataAsync(url){ return new Promise((resolve, reject) => {setTimeout(()=> { var res = {url: url,data: Math.random() } resolve(res)}, 1000) })} 使用 Generator 函數可以這樣寫

function*getData(){ var res1 = yield getDataAsync(’/page/1?param=123’) console.log(res1) var res2 = yield getDataAsync(`/page/2?param=${res1.data}`) console.log(res2) var res3 = yield getDataAsync(`/page/2?param=${res2.data}`) console.log(res3))} 然后我們這樣逐步執行

var g = getData()g.next().value.then(res1=> { g.next(res1).value.then(res2=> {g.next(res2).value.then(()=> { g.next()}) })}) 上面的代碼,我們逐步調用遍歷器的 next() 方法,由于每一個 next() 方法返回值的 value 屬性為一個 Promise 對象 所以我們為其添加 then 方法, 在 then 方法里面接著運行 next 方法挪移遍歷器指針,直到 Generator 函數運行完成,實際上,這個過程我們不必手動完成,可以封裝成一個簡單的執行器

function run(gen){ var g = gen() function next(data){var res = g.next(data)if (res.done) return res.valueres.value.then((data) => { next(data)}) } next()}

run 方法用來自動運行異步的 Generator 函數,其實就是一個遞歸的過程調用的過程。這樣我們就不必手動執行 Generator 函數了。 有了 run 方法,我們只需要這樣運行 getData 方法

run(getData)

這樣,我們就可以把異步操作封裝到 Generator 函數內部,使用 run 方法作為 Generator 函數的自執行器,來處理異步。其實我們不難發現, async/await 方法相比于 Generator 處理異步的方式,有很多相似的地方,只不過 async/await 在語義化方面更加明顯,同時 async/await 不需要我們手寫執行器,其內部已經幫我們封裝好了,這就是為什么說 async/await 是 Generator 函數處理異步的語法糖了

來自:http://blog.poetries.top/2017/08/27/js_cb_promise_generator_async/

標簽: JavaScript
相關文章:
主站蜘蛛池模板: 郑州爱婴幼师学校_专业幼师培训_托育师培训_幼儿教育培训学校 | 培训中心-翰香原香酥板栗饼加盟店总部-正宗板栗酥饼技术 | ALC墙板_ALC轻质隔墙板_隔音防火墙板_轻质隔墙材料-湖北博悦佳 | 企典软件一站式企业管理平台,可私有、本地化部署!在线CRM客户关系管理系统|移动办公OA管理系统|HR人事管理系统|人力 | 私人别墅家庭影院系统_家庭影院音响_家庭影院装修设计公司-邦牛影音 | 结晶点测定仪-润滑脂滴点测定仪-大连煜烁 | 青岛美佳乐清洁工程有限公司|青岛油烟管道清洗|酒店|企事业单位|学校工厂厨房|青岛油烟管道清洗 插针变压器-家用电器变压器-工业空调变压器-CD型电抗器-余姚市中驰电器有限公司 | 标准品网_标准品信息网_【中检计量】 | 坏男孩影院-提供最新电影_动漫_综艺_电视剧_迅雷免费电影最新观看 | 运动木地板厂家,篮球场木地板品牌,体育场馆木地板安装 - 欧氏运动地板 | 广东恩亿梯电源有限公司【官网】_UPS不间断电源|EPS应急电源|模块化机房|电动汽车充电桩_UPS电源厂家(恩亿梯UPS电源,UPS不间断电源,不间断电源UPS) | 地图标注|微信高德百度地图标注|地图标记-做地图[ZuoMap.com] | 洛阳防爆合格证办理-洛阳防爆认证机构-洛阳申请国家防爆合格证-洛阳本安防爆认证代办-洛阳沪南抚防爆电气技术服务有限公司 | 不锈钢法兰-碳钢法兰-法兰盘生产加工厂家-[鼎捷峰]-不锈钢法兰-碳钢法兰-法兰盘生产加工厂家-[鼎捷峰] | 陕西视频监控,智能安防监控,安防系统-西安鑫安5A安防工程公司 | 螺旋丝杆升降机-SWL蜗轮-滚珠丝杆升降机厂家-山东明泰传动机械有限公司 | 温控器生产厂家-提供温度开关/热保护器定制与批发-惠州市华恺威电子科技有限公司 | 心肺复苏模拟人|医学模型|急救护理模型|医学教学模型上海康人医学仪器设备有限公司 | 长江船运_国内海运_内贸船运_大件海运|运输_船舶运输价格_钢材船运_内河运输_风电甲板船_游艇运输_航运货代电话_上海交航船运 | 浇注料-高铝砖耐火砖-郑州凯瑞得窑炉耐火材料有限公司 | POS机官网 - 拉卡拉POS机免费办理|官网在线申请入口 | 杭州ROHS检测仪-XRF测试仪价格-百科 | 广州番禺搬家公司_天河黄埔搬家公司_企业工厂搬迁_日式搬家_广州搬家公司_厚道搬迁搬家公司 | 精密光学实验平台-红外粉末压片机模具-天津博君 | 阜阳在线-阜阳综合门户| 横河变送器-横河压力变送器-EJA变送器-EJA压力变送器-「泉蕴仪表」 | 挤塑板-XPS挤塑板-挤塑板设备厂家[襄阳欧格]| EPK超声波测厚仪,德国EPK测厚仪维修-上海树信仪器仪表有限公司 | 北京银联移动POS机办理_收银POS机_智能pos机_刷卡机_收银系统_个人POS机-谷骐科技【官网】 | 煤机配件厂家_刮板机配件_链轮轴组_河南双志机械设备有限公司 | 小学教案模板_中学教师优秀教案_高中教学设计模板_教育巴巴 | 香蕉筛|直线|等厚|弧形|振动筛|香蕉筛厂家-洛阳隆中重工 | 水厂污泥地磅|污泥处理地磅厂家|地磅无人值守称重系统升级改造|地磅自动称重系统维修-河南成辉电子科技有限公司 | 德国EA可编程直流电源_电子负载,中国台湾固纬直流电源_交流电源-苏州展文电子科技有限公司 | 百度关键词优化_网站优化_SEO价格 - 云无限好排名 | 干粉砂浆设备-干粉砂浆生产线-干混-石膏-保温砂浆设备生产线-腻子粉设备厂家-国恒机械 | 不锈钢管件(不锈钢弯头,不锈钢三通,不锈钢大小头),不锈钢法兰「厂家」-浙江志通管阀 | 空调风机,低噪声离心式通风机,不锈钢防爆风机,前倾皮带传动风机,后倾空调风机-山东捷风风机有限公司 | 印刷人才网 印刷、包装、造纸,中国80%的印刷企业人才招聘选印刷人才网! | 脱硝喷枪-氨水喷枪-尿素喷枪-河北思凯淋环保科技有限公司 | 塑木弯曲试验机_铜带拉伸强度试验机_拉压力测试台-倾技百科 |