>  기사  >  웹 프론트엔드  >  JavaScript 소개: 손으로 쓴 비동기 추가 asyncAdd 메서드

JavaScript 소개: 손으로 쓴 비동기 추가 asyncAdd 메서드

WBOY
WBOY앞으로
2022-08-26 14:04:132562검색

이 글은 javascript에 대한 관련 지식을 제공합니다. 주로 JavaScript의 비동기 추가 asyncAdd 메소드에 대한 자세한 설명을 소개합니다. 도움이 필요한 친구들이 함께 살펴보도록 하겠습니다. 모두에게 도움이 됩니다.

JavaScript 소개: 손으로 쓴 비동기 추가 asyncAdd 메서드

[관련 권장사항: javascript video tutorial, web front-end]

Foreword

Nuggets에서 간단하지만 흥미로운 질문을 찾았습니다. 제목은 다음과 같습니다.

// 异步加法
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 기본 지식 간의 연관성을 확인해보세요. 보스는 피해주세요! 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

대부분의 사람들은 이 질문의 내용을 처음에는 알지 못하지만(말하지 않으면 아무도 모릅니다), 두 번째로 읽으면 구체적인 내용이 무엇인지 거의 이해하게 될 것입니다. 좋아요, 함께 분석해 봅시다! ! !

asyncAdd 분석🎜🎜최종 결론은 다음과 같습니다. 🎜
  • sum 부분의 내용만 수정 가능하며, sum은 매개변수를 받을 수 있습니다. 모든 길이의 li>
  • sumasyncAdd를 통해서만 덧셈 계산을 구현할 수 있습니다.
  • 비동기 논리는 sum에서 처리되어야 합니다. , Promise 사용이 필요함
  • sum 방법의 계산 시간을 최적화해야 함
🎜The 다음은 코드의 다양한 부분을 분석하여 얻은 관련 정보입니다. 🎜

직관적인 기본 요구 사항

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 달성 code> 함수 즉, <code>sum 부분의 내용만 수정할 수 있습니다.
  • 덧셈(+)은 직접 사용할 수 없으며, 추가는 asyncAdd
  • sum 메서드의 계산 시간 최적화

숨겨진 검사 지점—setTimeout 및 cb

const cash: any = {};
function isUndefined(target: any) {
    return target === void 0;
}
async function sum(...nums: number[]) {
    let res: any = 0;
    const key = nums.join(&#39;+&#39;);
    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);
        });
    })
}
🎜From 위 내용 중 가장 눈에 띄는 것은 setTimeoutcb입니다. 사실 setTimeout을 사용하고 있기 때문에 이해하기 어렵지 않습니다. >asyncAdd는 콜백 함수를 통해서만 전달될 수 있습니다. cb는 이 계산 결과를 반환합니다. 첫 번째 매개변수 null은 무엇을 나타냅니까? 🎜🎜사실, node에 대해 더 많이 알고 계시다면, node의 비동기 처리 콜백 함수가 일반적으로 첫 번째 매개변수는 오류 발생 시 후속 실행 로직을 맞춤화하기 위해 외부로 전달하는 데 사용되는 오류 객체입니다. 🎜🎜한 문장: cb 함수는 오류 객체와 계산 결과를 매개변수로 받아 외부로 전달하는 함수입니다. 🎜

숨겨진 검사 포인트 - async & wait

rrreee🎜위 부분에서 sum 메소드의 반환값은 promise 타입이어야 합니다 예, 왜냐하면 await sum(...) 형식이 앞에 명확하게 사용되어 있기 때문입니다. 🎜🎜또한 total 함수의 반환 값도 promise 유형이어야 합니다. 전체 total 함수가 async 비동기 함수, 자세한 내용을 보려면 여기를 클릭하세요. 🎜🎜한 문장: sumpromise 유형의 값을 반환해야 합니다. 즉, sum은 확실히 promise를 사용합니다. > 및 sum(1,2,3,4,5,6,4)를 통해 sum이 모든 길이의 매개변수를 받을 수 있다는 것을 알고 있습니다. 🎜🎜Implement asyncAdd🎜

특정 구현

🎜구현 아이디어는 다음과 같습니다.🎜
  • 외부 매개변수의 길이가 고정되어 있지 않다는 점을 고려하여 나머지 연산자를 사용하여 들어오는 매개변수를 모두 받습니다
  • asyncAdd의 비동기 작업을 고려하여 이를 Promise 구현, 즉 caculate 함수로 캡슐화합니다. li>
  • asyncAdd를 고려하면 계산을 위해 실제로 한 번에 두 개의 숫자만 수신할 수 있고 루프를 사용하여 여러 매개변수를 개별적으로 전달할 수 있습니다.
  • 처리되는 비동기 작업의 순서를 고려하면 루프를 통해 async/await를 사용하여 올바른 실행 순서를 보장하고 async 함수의 반환 값이 sum과 정확히 일치하며 다음과 같습니다. Promise 유형 요구 사항
🎜구체적인 코드는 다음과 같습니다:🎜rrreee

최적화

내부 함수 추출

  • caculate 함수는 sum 함수의 외부 레이어로 추출될 수 있습니다.
  • asyncAdd 콜백 함수 너무 많은 매개변수와 외부 메소드에 의존하기 때문에 함수를 추출할 필요가 없습니다. Multi
rrreee

캐시 계산 결과

🎜사실 를 잘 보면 >total 메서드에서 sum이 두 번 호출되고 매개변수는 여전히 동일하며, 목적은 동일한 콘텐츠를 계산할 때 캐시에서 직접 결과를 가져오라는 메시지를 표시하는 것입니다. 두 번째로 비동기 계산을 통하지 않고 🎜rrreee🎜다음은 간단한 캐싱 솔루션의 구현일 뿐입니다. 구체적인 구현은 다음과 같습니다. 🎜
const cash: any = {};
function isUndefined(target: any) {
    return target === void 0;
}
async function sum(...nums: number[]) {
    let res: any = 0;
    const key = nums.join(&#39;+&#39;);
    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 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 jb51.net에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제