摘要:而的主線程中不允許操作網(wǎng)絡(luò),更是將程序員們推向了異步的深淵。異步深淵產(chǎn)生的主要原因是回調(diào),這在里尤其嚴(yán)重。為了逃離回調(diào)的深淵,大家開始想各種辦法來(lái)把回調(diào)扁平化。目前已經(jīng)在等環(huán)境中得到支持,使用的不僅能大大簡(jiǎn)化代碼,還能降低邏輯思路的復(fù)雜度。
哦,代碼……就把它們當(dāng)成插圖吧
隨著 CPU 從單核變多核,軟件從注重功能到注重體驗(yàn),Web 從頁(yè)面跳轉(zhuǎn)方式到 Web2.0 的無(wú)刷新加載(AJAX),程序員越來(lái)越多的接觸多線程和異步。而 Android 的主線程中不允許操作網(wǎng)絡(luò),更是將程序員們推向了異步的深淵。異步深淵產(chǎn)生的主要原因是回調(diào),這在 nodejs 里尤其嚴(yán)重。
// [node.js] doFirstThing(function(err, data) { doSecondThing(data, function(err, data) { doThirdThing(data, function(err, data) { // ... fall down }) }); });
為了逃離回調(diào)的深淵,大家開始想各種辦法來(lái)把回調(diào)扁平化。
在 JavaScript 中,Promise(指該類方法而非某個(gè)庫(kù))成為眾多解決方案的佼佼者,并成功被 ES6 采納。
// [node.js] doFirstThing() .then(doSecondThing) .then(doThirdThing) // .then(...) - continuous .catch(function() { // something wrong });
而 C# 則通過 Task 和 ThreadPool 讓異步編程變得容易。前面談?wù)摰?C# 并行計(jì)算(Parallel 和 ParallelQuery) 就是基于 Task 的。不過使用 Task.ContinueWith() 和 Parallel.ForEach() 的時(shí)候,就會(huì)覺得:這不就是 Promise 嗎?
// [csharp] Task.Run(() => { // do first thing and return a data return "first"; }).ContinueWith(task => { // do second thing and return a data return new []{ task.Result, "second" }; }).ContinueWith(task => { // do final thing foreach (string s in task.Result) { Console.WriteLine(s); } }).Wait();
之后 C#5.0 又推出 async/await 方案,將異步代碼寫得像同步代碼一樣,由編譯器來(lái)將 async/await 代碼封裝成異步 Task 方式,而不是由人工處理,這大大降低了寫異步程序的門檻。
// [csharp] private async static Task Process() { string first = await Task.Run(() => "first"); string[] all = await Task.Run(() => { return new [] { first, "second" }; }); await(Task.Run(() => { foreach (string s in all) { Console.WriteLine(s); } })); }
JavaScript 程序員們一邊在等著 ES7 的 async/await 特性,一邊也沒閑著,在 ES6 generator/yield 特性基礎(chǔ)上開發(fā)了個(gè) co 出來(lái),提供了類似于 async/await 特性的異步編程方式。
// [node.js] var co = require("co"); co(function*() { var first = yield new Promise(function(resolve) { setTimeout(function() { resolve("first"); }, 100); }); var all = yield new Promise(function(resolve) { setTimeout(function() { resolve([first, "second"]) }, 200); }) console.log(all); }); // [ "first", "second" ]
不過 co 程序?qū)懫饋?lái)又要寫 Generator,又要用 yeild,還常常要封裝 Promise,代碼仍然不夠簡(jiǎn)潔。目前 async/await 已經(jīng)在 TypeScript、Babel、Node 7.6+ 等環(huán)境中得到支持,使用 JavaScript 的 async/await 不僅能大大簡(jiǎn)化代碼,還能降低邏輯思路的復(fù)雜度。
2018.1.18 更新,因?yàn)?async/await 早已進(jìn)入實(shí)踐階段
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/85974.html
摘要:?jiǎn)栴}的主要目的是考察對(duì)異步調(diào)用執(zhí)行結(jié)果的處理,既然是異步調(diào)用,那么不可能同步等待異步結(jié)果,結(jié)果一定是異步的經(jīng)常用來(lái)模擬異步操作。 問題 原題來(lái)自 @若澤 的提問。 可修改下面的 aa() 函數(shù),目的是在一秒后用 console.log() 輸出 want-value function aa() { setTimeout(function() { return w...
摘要:和異步處理調(diào)用訪問數(shù)據(jù)采用的方式,這是一個(gè)異步過程,異步過程最基本的處理方式是事件或回調(diào),其實(shí)這兩種處理方式實(shí)現(xiàn)原理差不多,都需要在調(diào)用異步過程的時(shí)候傳入一個(gè)在異步過程結(jié)束的時(shí)候調(diào)用的接口。 Ajax 和異步處理 調(diào)用 API 訪問數(shù)據(jù)采用的 Ajax 方式,這是一個(gè)異步過程,異步過程最基本的處理方式是事件或回調(diào),其實(shí)這兩種處理方式實(shí)現(xiàn)原理差不多,都需要在調(diào)用異步過程的時(shí)候傳入一個(gè)在異...
摘要:因?yàn)楹瘮?shù)返回一個(gè)對(duì)象,所以可以用于等待一個(gè)函數(shù)的返回值這也可以說是在等函數(shù),但要清楚,它等的實(shí)際是一個(gè)返回值。幫我們干了啥作個(gè)簡(jiǎn)單的比較上面已經(jīng)說明了會(huì)將其后的函數(shù)函數(shù)表達(dá)式或的返回值封裝成一個(gè)對(duì)象,而會(huì)等待這個(gè)完成,并將其的結(jié)果返回出來(lái)。 隨著 Node 7 的發(fā)布,越來(lái)越多的人開始研究據(jù)說是異步編程終級(jí)解決方案的 async/await。我第一次看到這組關(guān)鍵字并不是在 JavaSc...
摘要:使用中間件后的也是通過中間件包裝后的。在的位置則進(jìn)行觸發(fā)監(jiān)聽器,監(jiān)聽器設(shè)置則在中增加。現(xiàn)在來(lái)解釋,和對(duì)應(yīng)關(guān)系我當(dāng)時(shí)回答的是對(duì)應(yīng)的函數(shù)名稱,如果一致的話就會(huì)執(zhí)行。呵呵,那個(gè)涂鴉大工程師有問題了如何綁定的呢,怎么確定是而不是。 redux 閑談 起因: 在與涂鴉智能一個(gè)web工程師交流過程中,他詢問我dispatch一個(gè)action,是如何和reducer 綁定的,dispatch(act...
閱讀 1135·2023-04-26 00:12
閱讀 3275·2021-11-17 09:33
閱讀 1069·2021-09-04 16:45
閱讀 1196·2021-09-02 15:40
閱讀 2181·2019-08-30 15:56
閱讀 2969·2019-08-30 15:53
閱讀 3557·2019-08-30 11:23
閱讀 1939·2019-08-29 13:54