Heim >Web-Frontend >js-Tutorial >Einführung in JavaScript: Handschriftliche asynchrone Additionsmethode asyncAdd

Einführung in JavaScript: Handschriftliche asynchrone Additionsmethode asyncAdd

WBOY
WBOYnach vorne
2022-08-26 14:04:132595Durchsuche

Dieser Artikel bringt Ihnen relevantes Wissen über Javascript. Er stellt Ihnen vor allem die detaillierte Erklärung der asynchronen Additionsmethode von JavaScript vor. Ich hoffe, dass wir gemeinsam einen Blick darauf werfen an alle.

Einführung in JavaScript: Handschriftliche asynchrone Additionsmethode asyncAdd

[Verwandte Empfehlungen: Javascript-Video-Tutorial, Web-Frontend]

Vorwort

Ich habe eine einfache, aber interessante Frage zu Nuggets gefunden. Der Titel lautet wie folgt:

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

Sie können es versuchen Um es direkt umzusetzen und den Zusammenhang zwischen Ihrem eigenen Denken und den Grundkenntnissen von JavaScript zu überprüfen, vermeiden Sie es bitte! 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

Ich schätze, die meisten Leute wissen auf den ersten Blick nicht, worum es in dieser Frage geht (niemand kennt mich, wenn ich es dir nicht erzähle), aber nachdem ich sie zum zweiten Mal gelesen habe, verstehen sie wohl fast, was der konkrete Inhalt ist soll getestet werden. Okay, lasst es uns gemeinsam analysieren! ! !

Analyse von asyncAdd🎜🎜Hier ist die endgültige Schlussfolgerung: 🎜
  • Nur der Inhalt des Teils sum kann geändert werden und sum kann Parameter empfangen beliebiger Länge li>
  • sum kann die Additionsberechnung nur über asyncAdd
  • implementieren. Asynchrone Logik muss in sum verarbeitet werden , was erfordert Die Verwendung von Promise
  • muss die Berechnungszeit der sum-Methode optimieren
🎜Die Im Folgenden werden verschiedene Teile des Codes analysiert und die relevanten Informationen ermittelt. 🎜

Intuitive Grundanforderungen

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]
}
🎜Am intuitivsten können Sie anhand des obigen Textbeschreibungsteils leicht die spezifischen Anforderungen der Frage erkennen: 🎜
  • Erreichen Sie sum code>-Funktion, das heißt, sie kann nur den Inhalt des <code>sum-Teils ändern
  • Addition (+) kann nicht direkt verwendet werden und Addition wird über asyncAdd
  • Optimieren Sie die Berechnungszeit der sum-Methode

Versteckter Inspektionspunkt – 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 Der obige Inhalt ist der offensichtlichste setTimeout und cb. Tatsächlich ist dies nicht schwer zu verstehen, da setTimeout in asyncAdd und kann nur über die Rückruffunktion cb übergeben werden. Gibt das Ergebnis dieser Berechnung zurück. Was stellt der erste Parameter null dar? 🎜🎜Tatsächlich kann es als Fehlermeldungsobjekt betrachtet werden. Wenn Sie mehr über node wissen, wissen Sie, dass die Rückruffunktion für die asynchrone Verarbeitung in node normalerweise über Folgendes verfügt erster Parameter Es ist das Fehlerobjekt, das zur Weitergabe nach außen verwendet wird, um die nachfolgende Ausführungslogik anzupassen, wenn ein Fehler auftritt. 🎜🎜Ein Satz: Die Funktion cb empfängt das Fehlerobjekt und das Berechnungsergebnis als Parameter und gibt sie nach außen weiter. 🎜

Versteckter Inspektionspunkt – asynchron und warten

rrreee🎜Aus dem obigen Teil muss der Rückgabewert der sum-Methode vom Typ promise sein. Ja, weil vorne eindeutig die Form von await sum(...) verwendet wird. 🎜🎜Darüber hinaus muss der Rückgabewert der Funktion total ebenfalls vom Typ promise sein, da die gesamte Funktion total als async Asynchrone Funktion, klicken Sie hier, um Details anzuzeigen. 🎜🎜Ein Satz: sum muss einen Wert vom Typ promise zurückgeben, das heißt, sum wird definitiv promiseverwenden > und Aus sum(1,2,3,4,5,6,4) können wir sehen, dass sum Parameter beliebiger Länge empfangen kann. 🎜🎜AsyncAdd implementieren🎜

Spezifische Implementierung

🎜Die Implementierungsidee lautet wie folgt:🎜
  • Da die Länge externer Parameter nicht festgelegt ist, verwenden Sie den Restoperator, um alle eingehenden Parameter zu empfangen
  • Betrachten Sie die asynchrone Operation in asyncAdd und kapseln Sie sie als Implementierung von Promise, also der Funktion caculate li>
  • In Anbetracht dessen kann asyncAdd tatsächlich nur zwei Zahlen gleichzeitig zur Berechnung empfangen und verwendet eine Schleife, um mehrere Parameter separat zu übergeben.
  • In Anbetracht der Reihenfolge der Verarbeitung asynchroner Vorgänge Durch Schleifen verwenden Sie async/await, um die korrekte Ausführungssequenz sicherzustellen, und der Rückgabewert der Funktion async stimmt genau mit der sum überein und ist von Anforderungen für den Typ Promise
🎜Der spezifische Code lautet wie folgt:🎜rrreee

Optimieren

Innere Funktionen extrahieren

  • caculate Die Funktion kann in die äußere Schicht der sum-Funktion extrahiert werden
  • asyncAdd Die Rückruffunktion von Die Funktion muss nicht extrahiert werden, da sie auf zu vielen Parametern und externen Methoden basiert. Multi
rrreee

Cache-Berechnungsergebnisse

🎜In der Tat, wenn Sie sich den total-Methode, sum wird zweimal aufgerufen und Die Parameter sind immer noch dieselben. Der Zweck besteht darin, Sie aufzufordern, die Ergebnisse direkt aus dem Cache abzurufen, wenn derselbe Inhalt für berechnet wird zweites Mal statt durch asynchrone Berechnung. 🎜rrreee🎜Das Folgende ist nur eine Implementierung einer einfachen Caching-Lösung. Machen Sie sich keine allzu großen Sorgen. Die spezifische Implementierung ist wie folgt: 🎜
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前端

Das obige ist der detaillierte Inhalt vonEinführung in JavaScript: Handschriftliche asynchrone Additionsmethode asyncAdd. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:jb51.net. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen