Home >Web Front-end >JS Tutorial >Introduction to JavaScript: Handwritten asynchronous addition asyncAdd method

Introduction to JavaScript: Handwritten asynchronous addition asyncAdd method

WBOY
WBOYforward
2022-08-26 14:04:132603browse

This article brings you relevant knowledge about javascript. It mainly introduces the detailed explanation of JavaScript handwritten asynchronous addition asyncAdd method. Friends in need can refer to it. Let’s take a look. I hope it helps everyone.

Introduction to JavaScript: Handwritten asynchronous addition asyncAdd method

[Related recommendations: javascript video tutorial, web front-end

Preface

I found a simple but interesting question on Nuggets. The question is as follows:

// 异步加法
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(){
}

You can try to implement it directly and examine your own thinking and JavaScript basics How about the connection of knowledge? Boss, please take a detour!

I guess most people don’t know what this question is about at first glance (no one will know me if I don’t tell you), but after reading it for the second time, I guess they almost understand what it is. Let’s analyze what content we want to examine together! ! !

Analysis of asyncAdd

Here is the final conclusion:

  • Only the content of the sum part can be modified, sum Parameters of any length can be received in
  • sum. Addition calculation can only be realized through asyncAdd. In
  • sum, asynchronous processing is required. Logic, need to use Promise
  • Need to optimizesum The calculation time of the method

The following is an analysis of different parts of the code. , the relevant information obtained.

Intuitive basic requirements

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

The most intuitive way is through the above text description part, you can easily know the specific requirements of the question:

  • implementation The sum function can only modify the contents of the sum part.
  • Addition ( ) cannot be used directly. Addition is achieved through asyncAdd.
  • Optimization sum Calculation time of method

Hidden inspection point - setTimeout & cb

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

From the above content, the most obvious one is setTimeout and cb, in fact, this is not difficult to understand because setTimeout is used in asyncAdd. This can only be set through the callback function cb When the calculation results are returned, what does the first parameter null represent?

In fact, it can be considered as an error message object. If you know more about node, you will know that the asynchronous processing callback function in node is usually the first The first parameter is the error object, which is used to pass to the outside to customize subsequent execution logic when an error occurs.

One sentence: cb The function will receive the error object and the calculation result as parameters and pass them to the outside.

Hidden inspection point - 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]
}

From the above part, the return value of the sum method must be a promise Type, because the form await sum(...) is obviously used at the front.

In addition, the total function return value must also be a promise type, because the entire total function is defined as an async Asynchronous function, click here to view details.

One sentence: sum needs to return a value of type promise, that is, sum will definitely use promise, and From sum(1,2,3,4,5,6,4) we can see that sum can receive parameters of any length.

Implement asyncAdd

Specific implementation

The implementation ideas are as follows:

  • Considering that the length of external parameters is not fixed, use the remaining operator to receive all transmissions The input parameters
  • take into account the asynchronous operation in asyncAdd and encapsulate it as the implementation of Promise, that is, caculate function
  • Considering that asyncAdd can actually only receive two numbers at a time for calculation, multiple parameters are passed in in the form of a loop
  • Considering the order of processing asynchronous operations through loops, Use async/await to ensure the correct execution sequence, and the return value of the async function exactly meets the sum requirement of being a Promise type

The specific code is as follows:

// 通过 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;
}

Optimize

Extract the inner function

  • caculate The function can Extract to the outer layer of the sum function
  • asyncAdd There is no need to extract the callback function of the function because it relies on too many parameters and external methods
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;
}

Cache calculation results

In fact, if you carefully observe the total method, sum is called twice, and the parameters are still exactly the same. The purpose is to remind you The second time the same content is calculated the result is fetched directly from the cache instead of being calculated asynchronously.

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

The following is just an implementation of a simple caching solution. Don’t worry too much. The specific implementation is as follows:

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前端

The above is the detailed content of Introduction to JavaScript: Handwritten asynchronous addition asyncAdd method. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:jb51.net. If there is any infringement, please contact admin@php.cn delete