返回顶部
首页 > 资讯 > 前端开发 > JavaScript >JavaScript手写异步加法asyncAdd方法详解
  • 310
分享到

JavaScript手写异步加法asyncAdd方法详解

2024-04-02 19:04:59 310人浏览 薄情痞子
摘要

目录前言分析 asyncAdd直观的基本要求隐藏的考察点 — setTimeout & cb隐藏的考察点 — async & await实现

前言

在掘金上发现一道既简单但个人觉得还挺有意思的一道题,题目如下:

// 异步加法
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 基础知识的联系如何,大佬请绕行!

估计大多数人第一眼看下都不知道这题目到底要干啥(我不说就没人知道我也是),但是在看第二遍的时候估计就差不多明白具体是要考察什么内容了,下面就一起来分析分析吧!!!

分析 asyncAdd

这里先放置最终结论:

  • 只能修改 sum 部分的内容,sum 可接收任意长度的参数
  • sum 中只能通过 asyncAdd 实现加法计算
  • sum 中需要处理异步逻辑,需要使用 Promise
  • 需要优化 sum 方法的计算时间

下面是分别通过对代码的不同部分进行分析,获取到的相关的信息。

直观的基本要求

// 实现下 sum 函数。注意不能使用加法,在 sum 中借助 asyncAdd 完成加法。尽可能的优化这个方法的时间。 
function sum(){ }

最直观的方式就是通过上述的文字描述部分,可以很容易知道题目具体要求:

  • 实现 sum 函数,即只能修改 sum 部分的内容
  • 不能直接使用加法(+),通过 asyncAdd 实现加法
  • 优化 sum 方法的计算时间

隐藏的考察点 — setTimeout & cb

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

从上述内容来看,最明显的就是 setTimeoutcb 了,其实这不难理解因为在 asyncAdd 中使用了 setTimeout 只能通过回调函数 cb 将本次计算结果返回出去,那其中的第一个参数 null 代表什么呢?

其实可以认为它是一个错误信息对象,如果你比较了解 node 的话,就会知道在 node 中的异步处理的回调函数通常第一个参数就是错误对象,用于传递给外部在发生错误时自定义后续执行逻辑等。

一句话: cb 函数会接收 错误对象 和 计算结果 作为参数传递给外部。

隐藏的考察点 — 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 方法的 返回值 肯定是一个 promise 类型的,因为最前面明显的使用了 await sum(...) 的形式。

另外 total 函数返回值也必然是一个 promise 类型,因为整个 total 函数被定义为了一个 async 异步函数,可点击此处查看详细内容。

一句话:sum 需要返回 promise 类型的值,即 sum 一定会使用到 promise,并且从 sum(1,2,3,4,5,6,4) 可知 sum 可接收任意长度的参数。

实现 asyncAdd

具体实现

实现思路如下:

  • 考虑到外部参数长度不固定,使用剩余运算符接收所有传入的参数
  • 考虑到 asyncAdd 中的异步操作,将其封装为 Promise 的实现,即 caculate 函数
  • 考虑到 asyncAdd 实际只能一次接收两个数字进行计算,使用循环的形式将多个参数分别传入
  • 考虑到通过循环处理异步操作的顺序问题,使用 async/await 来保证正确的执行顺序,且 async 函数的返回值正好符合 sumPromise 类型的要求

具体代码如下:

// 通过 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的资料请关注编程网其它相关文章!

--结束END--

本文标题: JavaScript手写异步加法asyncAdd方法详解

本文链接: https://lsjlt.com/news/165778.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • JavaScript手写异步加法asyncAdd方法详解
    目录前言分析 asyncAdd直观的基本要求隐藏的考察点 — setTimeout & cb隐藏的考察点 — async & await实现 ...
    99+
    2024-04-02
  • JavaScript之怎么手写asyncAdd方法
    这篇文章主要介绍了JavaScript之怎么手写asyncAdd方法的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇JavaScript之怎么手写asyncAdd方法文章都会有所...
    99+
    2024-04-02
  • JavaScript之instanceof方法手写示例详解
    目录方法介绍instanceof 是什么?instanceof 使用方式开始手写方法介绍 instanceof 是什么? 用于检测构造函数的 prototype 属性是否出现在某个实...
    99+
    2022-11-13
    JavaScript instanceof 方法 JavaScript instanceof
  • Android ListView异步加载图片方法详解
    本文实例讲述了Android ListView异步加载图片方法。分享给大家供大家参考,具体如下: 先说说这篇文章的优点把,开启线程异步加载图片,然后刷新UI显示图片,而且通过弱...
    99+
    2022-06-06
    方法 图片 listview Android
  • Promise和Generato中如何用同步方法写异步JavaScript
    这篇文章给大家介绍Promise和Generato中如何用同步方法写异步JavaScript,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。最近在写一个自己的网站的时候(可以观摩一下~C...
    99+
    2024-04-02
  • javascript实现异步的方法
    这篇文章给大家分享的是有关javascript实现异步的方法的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。javascript实现异步的方法:1、使用setTimeout方法;2、使用setImmediate 方...
    99+
    2023-06-14
  • JavaScript手写call,apply,bind方法
    目录前言改写this实现思路前期准备手写call方法手写apply方法手写bind方法前言 改变this指向在书写业务的时候经常遇到,我们经常采用以下方法进行改写 使用作用声明变量存...
    99+
    2024-04-02
  • JavaScript中的异步处理方法
    本篇内容介绍了“JavaScript中的异步处理方法”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!在 JavaScript 的世界中,所有代...
    99+
    2023-06-17
  • 详解Android的OkHttp包编写异步HTTP请求调用的方法
    OkHttp 除了支持常用的同步 HTTP 请求之外,还支持异步 HTTP 请求调用。在使用同步调用时,当前线程会被阻塞,直到 HTTP 请求完成。当同时发出多个 HTTP 请...
    99+
    2022-06-06
    okhttp 调用 方法 http请求 Android
  • JavaScript异步操作同步执行的方法
    本文小编为大家详细介绍“JavaScript异步操作同步执行的方法”,内容详细,步骤清晰,细节处理妥当,希望这篇“JavaScript异步操作同步执行的方法”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深...
    99+
    2024-04-02
  • 详解Java中异步转同步的六种方法
    目录一、问题应用场景二、分析三、实现方法1.轮询与休眠重试机制2.wait/notify3.Lock Condition4.CountDownLatch5.CyclicBarrier...
    99+
    2024-04-02
  • 异步的含义以及JavaScript异步编程的方法
    本篇内容主要讲解“异步的含义以及JavaScript异步编程的方法”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“异步的含义以及JavaScript异步编程的方法...
    99+
    2024-04-02
  • RUST异步流处理方法详细讲解
    目录Stream 特质yield 匿名流try_joinselectSELECT宏几个条件async 问号使用Send traitStream 特质 在同步Rust 中流的...
    99+
    2022-12-16
    RUST异步流处理 RUST流处理
  • java中重写父类方法加不加@Override详解
    java重写父类方法加不加@Override 这个是我在刚学习java时遇到的问题,希望能给像我一样的新手学习时带来帮助,如有错误请指正,谢谢! class Father{ ...
    99+
    2024-04-02
  • JavaScript前端超时异步操作的解决方法
    今天就跟大家聊聊有关JavaScript前端超时异步操作的解决方法,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。自从 ECMAScript 的 Promise ES2015...
    99+
    2023-06-21
  • javascript的异步操作方法是什么
    这篇“javascript的异步操作方法是什么”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇...
    99+
    2024-04-02
  • Vue3异步组件Suspense的使用方法详解
    Suspense组件 官网中有提到他是属于实验性功能:<Suspense> 是一项实验性功能。它不一定会最终成为稳定功能,并且在稳定之前相关 API 也可能会发...
    99+
    2023-01-28
    Vue3异步组件 Vue3异步组件Suspense的使用方法
  • 异步加载CSS的方法有哪些
    这篇文章主要介绍“异步加载CSS的方法有哪些”,在日常操作中,相信很多人在异步加载CSS的方法有哪些问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”异步加载CSS的方法有哪些”...
    99+
    2024-04-02
  • Spring方法中调用异步方法进行事务控制详解
    Spring 异步事务控制 文章目录 Spring 异步事务控制Spring 事务源码逻辑一、事务拦截器拦截二、进行事务控制三、事务开启 / 回滚 /提交操作四、事务完成,清除事务信息简单总结 异步方法事务控制方案一:自身编码...
    99+
    2023-08-20
    spring java 数据库 mysql
  • 异步JavaScript编程中的Promise使用方法
    异步? 我在很多地方都看到过异步(Asynchronous)这个词,但在我还不是很理解这个概念的时候,却发现自己常常会被当做“已经很清楚”(* ̄? ̄)。 如果你也有类似的情况,没关系,搜索一下这个...
    99+
    2022-06-04
    使用方法 JavaScript Promise
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作