<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
在掘金上發現一道既簡單但個人覺得還挺有意思的一道題,題目如下:
// 非同步加法 function asyncAdd(a,b,cb){ setTimeout(() => { cb(null, a + b) }, Math.random() * 1000) } async function total(){ const res1 = await sum(1,2,3,4,5,6,4) const res2 = await sum(1,2,3,4,5,6,4) return [res1, res2] } total() // 實現下 sum 函數。注意不能使用加法,在 sum 中藉助 asyncAdd 完成加法。儘可能的優化這個方法的時間。 function sum(){ }
你可以直接嘗試實現下,考察下自己的思維和 JavaScript
基礎知識的聯絡如何,大佬請繞行!
估計大多數人第一眼看下都不知道這題目到底要幹啥(我不說就沒人知道我也是),但是在看第二遍的時候估計就差不多明白具體是要考察什麼內容了,下面就一起來分析分析吧!!!
這裡先放置最終結論:
sum
部分的內容,sum
可接收任意長度的引數sum
中只能通過 asyncAdd
實現加法計算sum
中需要處理非同步邏輯,需要使用 Promise
sum
方法的計算時間下面是分別通過對程式碼的不同部分進行分析,獲取到的相關的資訊。
// 實現下 sum 函數。注意不能使用加法,在 sum 中藉助 asyncAdd 完成加法。儘可能的優化這個方法的時間。 function sum(){ }
最直觀的方式就是通過上述的文字描述部分,可以很容易知道題目具體要求:
sum
函數,即只能修改 sum
部分的內容asyncAdd
實現加法sum
方法的計算時間// 非同步加法 function asyncAdd(a, b, cb){ setTimeout(() => { cb(null, a + b) }, Math.random() * 1000) }
從上述內容來看,最明顯的就是 setTimeout
和 cb
了,其實這不難理解因為在 asyncAdd
中使用了 setTimeout
只能通過回撥函數 cb
將本次計算結果返回出去,那其中的第一個引數 null
代表什麼呢?
其實可以認為它是一個錯誤資訊物件,如果你比較瞭解 node
的話,就會知道在 node
中的非同步處理的回撥函數通常第一個引數就是錯誤物件,用於傳遞給外部在發生錯誤時自定義後續執行邏輯等。
一句話: cb
函數會接收 錯誤物件 和 計算結果 作為引數傳遞給外部。
async function total(){ const res1 = await sum(1,2,3,4,5,6,4) const res2 = await sum(1,2,3,4,5,6,4) return [res1, res2] }
從上述的這部分來看,sum
方法的 返回值 肯定是一個 promise
型別的,因為最前面明顯的使用了 await sum(...)
的形式。
另外 total
函數返回值也必然是一個 promise
型別,因為整個 total
函數被定義為了一個 async
非同步函數,可點選此處檢視詳細內容。
一句話:sum
需要返回 promise
型別的值,即 sum
一定會使用到 promise
,並且從 sum(1,2,3,4,5,6,4)
可知 sum
可接收任意長度的引數。
實現思路如下:
asyncAdd
中的非同步操作,將其封裝為 Promise
的實現,即 caculate
函數asyncAdd
實際只能一次接收兩個數位進行計算,使用迴圈的形式將多個引數分別傳入async/await
來保證正確的執行順序,且 async
函數的返回值正好符合 sum
是 Promise
型別的要求具體程式碼如下:
// 通過 ES6 的剩餘運運算元(...) 接收外部傳入長度不固定的引數 async function sum(...nums: number[]) { // 封裝 Promise function caculate(num1: number, num2: number) { return new Promise((resolve, reject) => { // 呼叫 asyncAdd 實現加法 asyncAdd(num1, num2, (err: any, rs: number) => { // 處理錯誤邏輯 if (err) { reject(err); return; } // 向外部傳遞對應的計算結果 resolve(rs); }); }) } let res: any = 0; // 通過遍歷將引數一個個進行計算 for (const n of nums) { // 為了避免非同步執行順序問題,使用 await 等待執行結果 res = await caculate(res, n); } return res; }
caculate
函數可抽離到 sum
函數外層asyncAdd
函數的回撥函數沒必要抽離,因為它依賴的引數和外部方法太多function caculate(num1: number, num2: number) { return new Promise((resolve, reject) => { asyncAdd(num1, num2, (err: any, rs: number) => { if (err) { reject(err); return; } resolve(rs); }); }) } async function sum(...nums: number[]) { let res: any = 0; for (const n of nums) { res = await caculate(res, n); } return res; }
其實你仔細觀察 total
方法,其中 sum
呼叫了兩次,而且引數還是一模一樣的,目的就是提示你在第二次計算相同內容時結果直接 從快取中獲取,而不是在通過非同步計算。
async function total(){ const res1 = await sum(1,2,3,4,5,6,4) const res2 = await sum(1,2,3,4,5,6,4) return [res1, res2] }
以下只是一個簡單的快取方案的實現,不必過於糾結,具體實現如下:
const cash: any = {}; function isUndefined(target: any) { return target === void 0; } async function sum(...nums: number[]) { let res: any = 0; const key = nums.join('+'); if (!isUndefined(cash[key])) return cash[key]; for (const n of nums) { res = await caculate(res, n); } cash[key] = res; return res; } function caculate(num1: number, num2: number) { return new Promise((resolve, reject) => { asyncAdd(num1, num2, (err: any, rs: number) => { if (err) { reject(err); return; } resolve(rs); }); }) }
以上就是JavaScript手寫非同步加法asyncAdd方法詳解的詳細內容,更多關於JavaScript非同步加法asyncAdd的資料請關注it145.com其它相關文章!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45