亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

JavaScript手寫異步加法asyncAdd方法詳解

 更新時(shí)間:2022年08月23日 14:30:35   作者:熊的貓  
這篇文章主要為大家介紹了JavaScript手寫異步加法asyncAdd方法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

前言

在掘金上發(fā)現(xiàn)一道既簡單但個(gè)人覺得還挺有意思的一道題,題目如下:

// 異步加法
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()
// 實(shí)現(xiàn)下 sum 函數(shù)。注意不能使用加法,在 sum 中借助 asyncAdd 完成加法。盡可能的優(yōu)化這個(gè)方法的時(shí)間。
function sum(){
}

你可以直接嘗試實(shí)現(xiàn)下,考察下自己的思維和 JavaScript 基礎(chǔ)知識(shí)的聯(lián)系如何,大佬請(qǐng)繞行!

估計(jì)大多數(shù)人第一眼看下都不知道這題目到底要干啥(我不說就沒人知道我也是),但是在看第二遍的時(shí)候估計(jì)就差不多明白具體是要考察什么內(nèi)容了,下面就一起來分析分析吧?。?!

分析 asyncAdd

這里先放置最終結(jié)論:

  • 只能修改 sum 部分的內(nèi)容,sum 可接收任意長度的參數(shù)
  • sum 中只能通過 asyncAdd 實(shí)現(xiàn)加法計(jì)算
  • sum 中需要處理異步邏輯,需要使用 Promise
  • 需要優(yōu)化 sum 方法的計(jì)算時(shí)間

下面是分別通過對(duì)代碼的不同部分進(jìn)行分析,獲取到的相關(guān)的信息。

直觀的基本要求

// 實(shí)現(xiàn)下 sum 函數(shù)。注意不能使用加法,在 sum 中借助 asyncAdd 完成加法。盡可能的優(yōu)化這個(gè)方法的時(shí)間。 
function sum(){ }

最直觀的方式就是通過上述的文字描述部分,可以很容易知道題目具體要求:

  • 實(shí)現(xiàn) sum 函數(shù),即只能修改 sum 部分的內(nèi)容
  • 不能直接使用加法(+),通過 asyncAdd 實(shí)現(xiàn)加法
  • 優(yōu)化 sum 方法的計(jì)算時(shí)間

隱藏的考察點(diǎn) — setTimeout & cb

// 異步加法
function asyncAdd(a, b, cb){
  setTimeout(() => {
    cb(null, a + b)
  }, Math.random() * 1000)
}

從上述內(nèi)容來看,最明顯的就是 setTimeoutcb 了,其實(shí)這不難理解因?yàn)樵?asyncAdd 中使用了 setTimeout 只能通過回調(diào)函數(shù) cb 將本次計(jì)算結(jié)果返回出去,那其中的第一個(gè)參數(shù) null 代表什么呢?

其實(shí)可以認(rèn)為它是一個(gè)錯(cuò)誤信息對(duì)象,如果你比較了解 node 的話,就會(huì)知道在 node 中的異步處理的回調(diào)函數(shù)通常第一個(gè)參數(shù)就是錯(cuò)誤對(duì)象,用于傳遞給外部在發(fā)生錯(cuò)誤時(shí)自定義后續(xù)執(zhí)行邏輯等。

一句話: cb 函數(shù)會(huì)接收 錯(cuò)誤對(duì)象 和 計(jì)算結(jié)果 作為參數(shù)傳遞給外部。

隱藏的考察點(diǎn) — async & await

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 方法的 返回值 肯定是一個(gè) promise 類型的,因?yàn)樽钋懊婷黠@的使用了 await sum(...) 的形式。

另外 total 函數(shù)返回值也必然是一個(gè) promise 類型,因?yàn)檎麄€(gè) total 函數(shù)被定義為了一個(gè) async 異步函數(shù),可點(diǎn)擊此處查看詳細(xì)內(nèi)容。

一句話:sum 需要返回 promise 類型的值,即 sum 一定會(huì)使用到 promise,并且從 sum(1,2,3,4,5,6,4) 可知 sum 可接收任意長度的參數(shù)。

實(shí)現(xiàn) asyncAdd

具體實(shí)現(xiàn)

實(shí)現(xiàn)思路如下:

  • 考慮到外部參數(shù)長度不固定,使用剩余運(yùn)算符接收所有傳入的參數(shù)
  • 考慮到 asyncAdd 中的異步操作,將其封裝為 Promise 的實(shí)現(xiàn),即 caculate 函數(shù)
  • 考慮到 asyncAdd 實(shí)際只能一次接收兩個(gè)數(shù)字進(jìn)行計(jì)算,使用循環(huán)的形式將多個(gè)參數(shù)分別傳入
  • 考慮到通過循環(huán)處理異步操作的順序問題,使用 async/await 來保證正確的執(zhí)行順序,且 async 函數(shù)的返回值正好符合 sumPromise 類型的要求

具體代碼如下:

// 通過 ES6 的剩余運(yùn)算符(...) 接收外部傳入長度不固定的參數(shù)
async function sum(...nums: number[]) {
    // 封裝 Promise 
    function caculate(num1: number, num2: number) {
        return new Promise((resolve, reject) => {
            // 調(diào)用 asyncAdd 實(shí)現(xiàn)加法
            asyncAdd(num1, num2, (err: any, rs: number) => {
                // 處理錯(cuò)誤邏輯
                if (err) {
                    reject(err);
                    return;
                }
                // 向外部傳遞對(duì)應(yīng)的計(jì)算結(jié)果
                resolve(rs);
            });
        })
    }
    let res: any = 0;
    // 通過遍歷將參數(shù)一個(gè)個(gè)進(jìn)行計(jì)算
    for (const n of nums) {
        // 為了避免異步執(zhí)行順序問題,使用 await 等待執(zhí)行結(jié)果 
        res = await caculate(res, n);
    }
    return res;
}

進(jìn)行優(yōu)化

抽離內(nèi)層函數(shù)

  • caculate 函數(shù)可抽離到 sum 函數(shù)外層
  • asyncAdd 函數(shù)的回調(diào)函數(shù)沒必要抽離,因?yàn)樗蕾嚨膮?shù)和外部方法太多
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;
}

緩存計(jì)算結(jié)果

其實(shí)你仔細(xì)觀察 total 方法,其中 sum 調(diào)用了兩次,而且參數(shù)還是一模一樣的,目的就是提示你在第二次計(jì)算相同內(nèi)容時(shí)結(jié)果直接 從緩存中獲取,而不是在通過異步計(jì)算。

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]
}

以下只是一個(gè)簡單的緩存方案的實(shí)現(xiàn),不必過于糾結(jié),具體實(shí)現(xiàn)如下:

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方法詳解的詳細(xì)內(nèi)容,更多關(guān)于JavaScript異步加法asyncAdd的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 微信小程序的分類頁面制作

    微信小程序的分類頁面制作

    這篇文章主要介紹了微信小程序?qū)嵉姆诸愴撁嬷谱鞯南嚓P(guān)資料,需要的朋友可以參考下
    2017-06-06
  • fs-extra實(shí)現(xiàn)yarn?create?tlist創(chuàng)建示例詳解

    fs-extra實(shí)現(xiàn)yarn?create?tlist創(chuàng)建示例詳解

    這篇文章主要為大家介紹了fs-extra實(shí)現(xiàn)yarn?create?tlist創(chuàng)建示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-01-01
  • 微信小程序 設(shè)置啟動(dòng)頁面的兩種方法

    微信小程序 設(shè)置啟動(dòng)頁面的兩種方法

    這篇文章主要介紹了 微信小程序 設(shè)置啟動(dòng)頁面的方法的相關(guān)資料,這里對(duì)設(shè)置啟動(dòng)頁面的兩種方法分別介紹,需要的朋友可以參考下
    2017-03-03
  • 微信小程序 wx:key詳細(xì)介紹

    微信小程序 wx:key詳細(xì)介紹

    這篇文章主要介紹了微信小程序 wx:key詳細(xì)介紹的相關(guān)資料,并附簡單代碼實(shí)例,幫助大家學(xué)習(xí)理解,需要的朋友可以參考下
    2016-10-10
  • 微信小程序url與token設(shè)置詳解

    微信小程序url與token設(shè)置詳解

    這篇文章主要介紹了微信小程序url與token設(shè)置詳解的相關(guān)資料,希望通過本文能幫助到大家解決類似問題,需要的朋友可以參考下
    2017-09-09
  • 微信小程序 選擇器(時(shí)間,日期,地區(qū))實(shí)例詳解

    微信小程序 選擇器(時(shí)間,日期,地區(qū))實(shí)例詳解

    這篇文章主要介紹了微信小程序 選擇器(時(shí)間,日期,地區(qū))實(shí)例詳解的相關(guān)資料,這里提供了實(shí)例代碼及實(shí)現(xiàn)效果圖,幫助大家學(xué)習(xí)理解這部分知識(shí),需要的朋友可以參考下
    2016-11-11
  • 微信小程序之獲取當(dāng)前位置經(jīng)緯度以及地圖顯示詳解

    微信小程序之獲取當(dāng)前位置經(jīng)緯度以及地圖顯示詳解

    最近剛開始接觸微信小程序,在弄懂其結(jié)構(gòu)以及相關(guān)接口之后,準(zhǔn)備著手實(shí)現(xiàn)一個(gè)小程序,功能包括--獲取用戶當(dāng)前位置的經(jīng)緯度,在地圖上查看位置,通過地圖獲取不同位置的經(jīng)緯度。
    2017-05-05
  • 微信小程序 地圖(map)實(shí)例詳解

    微信小程序 地圖(map)實(shí)例詳解

    這篇文章主要介紹了微信小程序 地圖(map)實(shí)例詳解的相關(guān)資料,這里對(duì)微信小程序的地圖API 進(jìn)行了詳細(xì)介紹并附示例代碼和實(shí)現(xiàn)效果圖,需要的朋友可以參考下
    2016-11-11
  • next.js源碼解析getStaticProps?getStaticPaths使用場(chǎng)景

    next.js源碼解析getStaticProps?getStaticPaths使用場(chǎng)景

    這篇文章主要為大家介紹了next.js源碼解析getStaticProps?getStaticPaths使用場(chǎng)景,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-08-08
  • Iframe跨窗口通信原理詳解

    Iframe跨窗口通信原理詳解

    這篇文章主要為大家介紹了Iframe跨窗口通信原理詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-08-08

最新評(píng)論