本篇文章為大家帶來了關於javascript的相關知識,其中主要為大家介紹了JavaScript手寫異步加法asyncAdd方法詳解,有需要的朋友可以藉鑑參考下,下面一起來看一下,希望對大家有幫助。
【相關推薦:javascript影片教學、web前端】
##前言在掘金上發現一道既簡單但個人覺得還挺有趣的一道題,題目如下:// 异步加法 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可接收任意長度的參數
中只能透過
asyncAdd 實作加法計算
Promise
需要最佳化
直覺的基本要求
// 实现下 sum 函数。注意不能使用加法,在 sum 中借助 asyncAdd 完成加法。尽可能的优化这个方法的时间。 function sum(){ }
sum
部分的內容
不能直接使用加法(),透過
#優化
// 异步加法 function asyncAdd(a, b, cb){ setTimeout(() => { cb(null, a + b) }, Math.random() * 1000) }
和cb
了,其實這不難理解因為在asyncAdd
# 中使用了setTimeout
只能透過回呼函數cb
將本次計算結果回傳出去,那其中的第一個參數null
代表什麼呢? 其實可以認為它是一個錯誤訊息對象,如果你比較了解
的話,就會知道在node
中的非同步處理的回呼函數通常第一個參數就是錯誤對象,用於傳遞給外部在發生錯誤時自訂後續執行邏輯等。 一句話:
函數會接收 錯誤物件 和 計算結果 作為參數傳遞給外部。 隱藏的考察點— async & await
方法的回傳值肯定是一個promise
類型的,因為最前面明顯的使用了await sum(...)
的形式。 另外
函數傳回值也必然是一個promise
類型,因為整個total
函數被定義為了一個async
非同步函數,可點擊此處查看詳細內容。 一句話:
需要回傳promise
類型的值,也就是sum
一定會使用到promise
,並且由sum(1,2,3,4,5,6,4)
可知sum
可接收任意長度的參數。 實作asyncAdd
Promise
的實現,即caculate
函數
考慮到
考慮到透過循環處理非同步操作的順序問題,使用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; }
進行最佳化
sum
函數外層
#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; }
方法,其中sum
呼叫了兩次,而且參數還是一模一樣的,目的就是提示你在第二次計算相同內容時結果直接從快取中獲取,而不是在透過非同步計算。 <div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:js;">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]
}</pre><div class="contentsignin">登入後複製</div></div><div class="contentsignin">登入後複製</div></div>
以下只是一個簡單的快取方案的實現,不必過於糾結,具體實現如下:
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视频教程、web前端】
以上是JavaScript介紹之手寫非同步加法asyncAdd方法的詳細內容。更多資訊請關注PHP中文網其他相關文章!