日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術(shù)文章
文章詳情頁

深入淺出 JS 異步處理技術(shù)方案

瀏覽:198日期:2024-05-26 16:33:15

為什么要異步

'當(dāng)我們在星巴克買咖啡時,假設(shè)有100個人在排隊,也許咖啡的下單只要10S,但是咖啡的制作到客人領(lǐng)取咖啡要1000S。如果在同步的場景下,第一個客人下單到領(lǐng)取完咖啡要1010S才能輪到下一個客人,這在效率(某些場景)上來說會比較低下。如果我們異步處理這個流程,客人下單10S拿到憑證,客人就可以去做別的事情,并且10S后下一個客人可以繼續(xù)下單,并不阻礙流程。反而可以通過憑證,讓客人拿到自己的咖啡,也許時間上并不是第一個下單的客人先拿到。'

在網(wǎng)頁的世界里也是同樣的道理,不妨我們看看在執(zhí)行JS代碼的主線程里,如果遇到了AJAX請求,用戶事件等,如果不采用異步的方案,你會一直等待,等待第一個耗時的處理完成才能接上下一個JS代碼的執(zhí)行,于是界面就卡住了。

“也許有人會想,既然大家都說現(xiàn)在網(wǎng)頁上性能損耗最大的屬于DOM節(jié)點(diǎn)的操作,把這些搞成異步,行不行?其實(shí)這會帶來一個不確定性問題:既“成功”的狀態(tài)到底誰先來的問題。可以想象一下,如果我們在操作DOM,既給節(jié)點(diǎn)添加內(nèi)容,也給節(jié)點(diǎn)刪除,那么到底以誰為基準(zhǔn)呢?考慮到復(fù)雜性,也就可見一斑了。”

Event loop

雖然異步與event loop沒有太直接的關(guān)系,準(zhǔn)確的來講event loop 只是實(shí)現(xiàn)異步的一種機(jī)制。(了解為主)

“還是以上面咖啡館為例子,假定場景還是100人,這100人除了下單是與咖啡本身有關(guān)聯(lián)之外,其余的時間,比如看書,玩游戲的等可以視為自己的執(zhí)行邏輯。如果用event loop來給它做一個簡單的畫像,那么它就像:在與咖啡店店員溝通下單視為主執(zhí)行棧,咖啡的制作可以視為一個異步任務(wù),添加到一個任務(wù)隊列里,一直等帶100個人都下單完成,然后開始讀取任務(wù)隊列中的異步任務(wù),事件名就是下單憑證,如果有對應(yīng)的handler,那么就執(zhí)行叫對應(yīng)的客人來領(lǐng)取咖啡。這個過程,是循環(huán)不斷的。假設(shè)沒有客人來下單的時候,也就是店員處于空閑時間(可能自己去搞點(diǎn)別的)。”

傳統(tǒng)的Callback

假定一個asyncFetchDataSource函數(shù)用于獲取遠(yuǎn)程數(shù)據(jù)源,可能有20S。

function asyncFetchDataSource(cb){ (… 獲取數(shù)據(jù), function(response){ typeof cb === ’function’ && cb(response) })}

這種形式的callback可以適用于簡單場景,如果這里有一個更復(fù)雜的場景,比如獲取完數(shù)據(jù)源之后,依據(jù)id,獲取到某個數(shù)據(jù),在這某個數(shù)據(jù)中再依據(jù)id來更新某個列表,可以遇見的能看到代碼變成了:

asyncFetchDataSource(’’,function(data_a){ const { id_a } = data_a asyncFetchDataSource( id_a,function(data_b){ const { id_b } = data_b asyncFetchDataSource(id, function(data_c){ }) })})

如果有極端情況出現(xiàn),這里的callback就會變成無極限了。

Thunk函數(shù)

這是一種“傳名調(diào)用”的策略,表現(xiàn)的形式就是將參數(shù)放入一個臨時函數(shù),然后再將這個臨時函數(shù)傳入函數(shù)體內(nèi)。

function asyncFetchDataSource(url){ return function(callback){ fetch(url, callback) }}const dataSource = asyncFetchDataSource(’https://github.com/icepy’);dataSource(function(data){})

Promise

Promise正是想來處理這樣的異步編程,如果我們用Promise該如何處理一段Ajax?

function fetch(){ return new Promise(function(resolve,reject){ $.ajax({ url: ’xxx’, success:function(data){resolve(data) }, error:function(error){reject(error) } }) })}fetch().then(function(data){}).catch(function(error){})

Promise聲明周期:

進(jìn)行中(pending) 已經(jīng)完成(fulfilled) 拒絕(rejected)

如同上面Ajax的例子,我們可以很好的包裝一個函數(shù),讓fetch函數(shù)返回一個Promise對象。在Promise構(gòu)造函數(shù)里,可以傳入一個callback,并且在這里完成主體邏輯的編寫。唯一需要注意的是:Promise對象只能通過resolve和reject函數(shù)來返回,在外部使用then或catch來獲取。如果你直接拋出一個錯誤(throw new Error(’error’)),catch也是可以正確的捕獲到的。

Promise其他的方法

Promise.all(當(dāng)所有在可迭代參數(shù)中的 promises 已完成,或者第一個傳遞的 promise(指 reject)失敗時,返回 promise。)

var p1 = Promise.resolve(3);var p2 = 1337;var p3 = new Promise((resolve, reject) => { setTimeout(resolve, 100, 'foo');}); Promise.all([p1, p2, p3]).then(values => { console.log(values); // [3, 1337, 'foo'] });

Promise.race(返回一個新的 promise,參數(shù)iterable中只要有一個promise對象'完成(resolve)'或'失敗(reject)',新的promise就會立刻'完成(resolve)'或者'失敗(reject)',并獲得之前那個promise對象的返回值或者錯誤原因。)

var p1 = new Promise(function(resolve, reject) { setTimeout(resolve, 500, 'one'); });var p2 = new Promise(function(resolve, reject) { setTimeout(resolve, 100, 'two'); });Promise.race([p1, p2]).then(function(value) { console.log(value); // 'two' // 兩個都完成,但 p2 更快});

有趣的是如果你使用ES6的class,你是可以去派生Promise的。

class MePromise extends Promise{ // 處理 ...}

Generator

Generator可以輔助我們完成很多復(fù)雜的任務(wù),而這些基礎(chǔ)知識,又與iterator息息相關(guān),舉一個很簡單的例子,相信有很多朋友,應(yīng)該使用過co這個異步編程的庫,它就是用Generator來實(shí)現(xiàn),當(dāng)然它的設(shè)計會比例子要復(fù)雜的多,我們先來看一個co簡單的用法:

import co from ’co’co(function* () { var result = yield Promise.resolve(true); return result;}).then(function (value) { console.log(value);}, function (err) { console.error(err.stack);});

相應(yīng)的,我們來實(shí)現(xiàn)一個簡化的版本:

function co(task){ let _task = task() let resl = _task.next(); while(!resl.done){ console.log(resl); resl = _task.next(resl.value); }}function sayName(){ return { name: ’icepy’ }}function assign *(f){ console.log(f) let g = yield sayName() return Object.assign(g,{age:f});}co(function *(){ let info = yield *assign(18) console.log(info)})

雖然,這個例子中,還不能很好的看出來“異步”的場景,但是它很好的描述了Generator的使用方式。

從最開始的定義中,已經(jīng)和大家說明了,Generator最終返回的依然是一個迭代器對象,有了這個迭代器對象,當(dāng)你在處理某些場景時,你可以通過yield來控制,流程的走向。通過co函數(shù),我們可以看出,先來執(zhí)行next方法,然后通過一個while循環(huán),來判斷done是否為true,如果為true則代表整個迭代過程的結(jié)束,于是,這里就可以退出循環(huán)了。在Generator中的返回值,可以通過給next方法傳遞參數(shù)的方式來實(shí)現(xiàn),也就是遇上第一個yield的返回值。

有邏輯,自然會存在錯誤,在Generator捕獲錯誤的時機(jī)與執(zhí)行throw方法的順序有關(guān)系,一個小例子:

let hu = function *(){ let g = yield 1; try { let j = yield 2; } catch(e){ console.log(e) } return 34}let _it = hu();console.log(_it.next())console.log(_it.next())console.log(_it.throw(new Error(’hu error’)))

當(dāng)我能捕獲到錯誤的時機(jī)是允許完第二次的yield,這個時候就可以try了。

async await

async function createNewDoc() { let response = await db.post({}); // post a new doc return await db.get(response.id); // find by id}

https://tc39.github.io/ecmascript-asyncawait/

根據(jù)規(guī)范規(guī)定一個asnyc函數(shù)總是要返回一個Promise,從代碼直觀上來說,雖然簡潔了,但是async await并未萬能,它有很大的局限性,比如:

因?yàn)槭琼樞驁?zhí)行,假設(shè)有三個請求,那么這里并沒有很好的利用到異步帶來的止損(再包裝一個Promise.all) 如果要捕獲異常,需要去包try catch 缺少控制流程,比如progress(進(jìn)度)pause,resume等周期性的方法 沒有打斷的功能

主流的異步處理方案

我喜歡用co,而且社區(qū)使用也很廣泛, https://github.com/tj/co 。

co(function* () { var result = yield Promise.resolve(true); return result;}).then(function (value) { console.log(value);}, function (err) { console.error(err.stack);});

babel polyfill 支持,在瀏覽器環(huán)境中使用異步解決方案

如果你想使用全的polyfiil,直接npm install --save babel-polyfill,然后在webpack里進(jìn)行配置即可。

module.exports = { entry: ['babel-polyfill', './app/js']};

當(dāng)然由于我目前的開發(fā)基于的瀏覽器都比較高,所以我一般是挑選其中的:

https://github.com/facebook/regenerator/tree/master/packages/regenerator-runtime https://github.com/facebook/regenerator/tree/master/packages/regenerator-transform

如果你要使用async await 配置上 http://babeljs.io/docs/plugins/transform-async-to-generator/ 即可

Node.js 環(huán)境中使用異步解決方案

由于本人的node使用的LTS已經(jīng)是8.9.3版本了,所以大部分情況下已經(jīng)不再使用babel去進(jìn)行轉(zhuǎn)換,而是直接使用co這樣的庫。當(dāng)然co也不是萬能,一定要根據(jù)業(yè)務(wù)場景,與其他異步處理的方式,配合中使用。

總結(jié) 相信未來的JS編程,只會越來越簡單,不要拘泥于語法,語言上的特性,不妨多看一看“外面的世界“。

來自:http://www.iteye.com/news/32831

標(biāo)簽: JavaScript
相關(guān)文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
国产免费av国片精品草莓男男| 日本中文字幕一区二区| 国产精品亚洲四区在线观看| 日韩欧美中文字幕在线视频| 婷婷五月色综合香五月| 日韩黄色av| 国产调教一区二区三区| 天堂√中文最新版在线| 欧美亚洲日本精品| 欧美日韩免费观看视频| 久久天堂av| 亚洲大全视频| 视频一区中文字幕国产| 五月激激激综合网色播| 日韩国产欧美视频| 国产日韩欧美一区二区三区 | 欧美日韩激情在线一区二区三区| 久久久精品久久久久久96 | 91精品丝袜国产高跟在线| 日本色综合中文字幕| 欧美激情五月| 高清av不卡| 五月综合激情| 少妇精品久久久一区二区 | 日韩精品导航| 91亚洲精品在看在线观看高清| 国产乱码精品一区二区亚洲| 九九九精品视频| 国产+成+人+亚洲欧洲在线| 亚洲精品一区三区三区在线观看| 亚洲性视频h| 蜜臀a∨国产成人精品| 国产精品色婷婷在线观看| 日韩亚洲国产欧美| 国产欧美丝祙| 成人日韩精品| 男女激情视频一区| 国产一级成人av| yellow在线观看网址| 国产专区一区| 亚洲精品日韩久久| 国产一区二区亚洲| 伊人久久亚洲影院| 国产美女亚洲精品7777| 蜜臀国产一区| 蜜臀精品一区二区三区在线观看| 国产欧美丝祙| 精品一区毛片| 欧美日韩xxxx| 久久久久国产精品一区二区| 免费观看在线色综合| 蜜桃久久久久| 亚洲专区一区| 激情久久一区二区| 久久午夜精品一区二区| 国产伦精品一区二区三区视频 | 中文字幕日韩亚洲| 久久69成人| 国产偷自视频区视频一区二区| 国产精品久久久久77777丨| 99久精品视频在线观看视频| 在线精品一区| 岛国av在线播放| 午夜久久黄色| 国产精品tv| 国产农村妇女精品一二区| 欧美日本不卡| 亚洲国产一区二区在线观看 | 国产精品视频3p| 好吊一区二区三区| 精品国产麻豆| 午夜久久av| 91精品国产调教在线观看| 国产精品成人自拍| 日韩一区二区久久| 中文字幕在线官网| 国产亚洲一区二区三区不卡| 最新日韩欧美| 中文在线免费视频| 国产日韩欧美一区| 美女黄网久久| 日本少妇一区| 麻豆精品国产91久久久久久| 精品国产中文字幕第一页| 亚洲尤物av| 欧美日韩一区二区综合| 麻豆精品蜜桃视频网站| 午夜天堂精品久久久久| 香蕉精品视频在线观看| 精品国产午夜肉伦伦影院| 亚洲精品护士| 国产精品试看| 久久高清免费| 国产自产自拍视频在线观看| 国产极品嫩模在线观看91精品| 亚洲伊人影院| 日韩视频二区| 欧美粗暴jizz性欧美20| 四虎4545www国产精品 | 欧美黑人做爰爽爽爽| 日本一区免费网站| 免费日本视频一区| 欧美大黑bbbbbbbbb在线| 久久精品国产99国产| 欧美色综合网| 日韩精品视频一区二区三区| 丝袜美腿亚洲一区| 日韩亚洲在线| 欧美女激情福利| 欧美va天堂在线| 香蕉久久99| 国产综合亚洲精品一区二| 日韩欧美另类一区二区| 麻豆mv在线观看| 国产美女高潮在线| av最新在线| 日本欧美国产| 亚洲啊v在线| 精品色999| 国产一区二区三区久久| 国产福利91精品一区二区| 美女视频免费精品| 夜夜嗨一区二区| 噜噜噜久久亚洲精品国产品小说| 欧美综合二区| 在线观看一区| 日韩中文av| 日韩精品久久理论片| 91精品在线免费视频| 欧美精品福利| 久久不见久久见国语| 国产精品v一区二区三区| 欧美国产极品| 久久精品三级| 亚洲美女久久精品| 欧美综合另类| 欧美在线网站| 蜜桃久久久久久| 日韩一区二区三区在线看| 欧美色综合网| 精品国产中文字幕第一页| 日韩免费看片| 欧美日韩国产在线观看网站| 西西人体一区二区| 亚洲专区视频| 91精品国产自产在线丝袜啪| 国产美女视频一区二区| 精品日产乱码久久久久久仙踪林| 欧美国产日本| 韩国三级一区| 午夜在线视频一区二区区别| 亚洲精品观看| 国产精品115| 久久国产主播| 日韩一区精品字幕| 国产精品久久久免费| 国产日韩电影| 亚洲免费精品| 欧美日韩一区自拍| 亚洲午夜天堂| 久久亚洲欧美| 国产福利亚洲| 久久婷婷av| 久久国产成人| 国产极品一区| 尤物tv在线精品| 日韩成人在线看| 国产资源在线观看入口av| 中文在线不卡| 麻豆一区二区三区| 久久高清精品| 深夜福利一区| 天堂√中文最新版在线| 日韩精品一二区| 国产一区二区三区四区大秀| 欧美日韩视频| 久久99久久久精品欧美| 午夜av一区| 国产色噜噜噜91在线精品| 国产一区福利| 先锋影音国产一区| 激情久久一区二区| 欧美在线影院| 久久久亚洲欧洲日产| 国产精品社区| 精品国产精品国产偷麻豆| 亚洲欧美激情诱惑| 精品一区av| 首页亚洲欧美制服丝腿| 日韩av有码| 日韩精品国产精品| 欧美影院三区| 国产极品一区| 欧美在线亚洲综合一区| 麻豆精品在线观看| 亚洲深夜福利| 国产suv精品一区| 日韩国产欧美一区二区三区| 99成人超碰| 国产乱码精品一区二区三区四区 |