Maison > Article > interface Web > Introduction à JavaScript : méthode asyncAdd d'addition asynchrone manuscrite
Cet article vous apporte des connaissances pertinentes sur javascript. Il vous présente principalement l'explication détaillée de la méthode asyncAdd d'ajout asynchrone manuscrite de JavaScript. Les amis dans le besoin peuvent s'y référer ensemble. à tout le monde aide.
[Recommandations associées : tutoriel vidéo javascript, front-end web]
J'ai trouvé une question simple mais intéressante sur Nuggets Le titre est le suivant :
// 异步加法 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(){ }
Vous, vous pouvez essayer. pour l'implémenter directement et examiner le lien entre votre propre réflexion et les connaissances de base de JavaScript
, évitez-le ! JavaScript
基础知识的联系如何,大佬请绕行!
估计大多数人第一眼看下都不知道这题目到底要干啥(我不说就没人知道我也是),但是在看第二遍的时候估计就差不多明白具体是要考察什么内容了,下面就一起来分析分析吧!!!
这里先放置最终结论:
sum
部分的内容,sum
可接收任意长度的参数sum
中只能通过 asyncAdd
实现加法计算sum
中需要处理异步逻辑,需要使用 Promise
sum
方法的计算时间下面是分别通过对代码的不同部分进行分析,获取到的相关的信息。
// 实现下 sum 函数。注意不能使用加法,在 sum 中借助 asyncAdd 完成加法。尽可能的优化这个方法的时间。 function sum(){ }
最直观的方式就是通过上述的文字描述部分,可以很容易知道题目具体要求:
sum
函数,即只能修改 sum
部分的内容asyncAdd
实现加法sum
方法的计算时间// 异步加法 function asyncAdd(a, b, cb){ setTimeout(() => { cb(null, a + b) }, Math.random() * 1000) }
从上述内容来看,最明显的就是 setTimeout
和 cb
了,其实这不难理解因为在 asyncAdd
中使用了 setTimeout
只能通过回调函数 cb
将本次计算结果返回出去,那其中的第一个参数 null
代表什么呢?
其实可以认为它是一个错误信息对象,如果你比较了解 node
的话,就会知道在 node
中的异步处理的回调函数通常第一个参数就是错误对象,用于传递给外部在发生错误时自定义后续执行逻辑等。
一句话: cb
函数会接收 错误对象 和 计算结果 作为参数传递给外部。
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
中的异步操作,将其封装为 Promise
的实现,即 caculate
函数asyncAdd
实际只能一次接收两个数字进行计算,使用循环的形式将多个参数分别传入async/await
来保证正确的执行顺序,且 async
函数的返回值正好符合 sum
是 Promise
类型的要求具体代码如下:
// 通过 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
sum
peut être modifié, et sum
peut recevoir des paramètres de n'importe quelle longueur li>somme
ne peut implémenter le calcul d'addition que via asyncAdd
somme
, qui nécessite l'utilisation de Promesse
somme
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] }🎜La manière la plus intuitive consiste à utiliser la partie de description du texte ci-dessus, vous pouvez facilement connaître les exigences spécifiques de la question : 🎜
somme code>, c'est-à-dire qu'elle ne peut modifier que le contenu de la partie <code>somme
asyncAdd
sum
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); }); }) }🎜From Dans le contenu ci-dessus, le plus évident est
setTimeout
et cb
. En fait, ce n'est pas difficile à comprendre car setTimeout
est utilisé dans null
? 🎜🎜En fait, il peut être considéré comme un objet de message d'erreur. Si vous en savez plus sur node
, vous saurez que la fonction de rappel de traitement asynchrone dans node
a généralement le premier paramètre C'est l'objet d'erreur, qui est utilisé pour passer à l'extérieur pour personnaliser la logique d'exécution ultérieure lorsqu'une erreur se produit. 🎜🎜Une phrase : La fonction cb
recevra l'objet d'erreur et le résultat du calcul en paramètres et les transmettra à l'extérieur. 🎜sum
doit être de type promise
Oui, car la forme await sum(...)
est clairement utilisée au début. 🎜🎜De plus, la valeur de retour de la fonction total
doit également être de type promise
, car toute la fonction total
est définie comme un async Fonction asynchrone, cliquez ici pour afficher les détails. 🎜🎜Une phrase : sum
doit renvoyer une valeur de type promise
, c'est-à-dire que sum
utilisera certainement promise
, et De sum(1,2,3,4,5,6,4)
nous pouvons voir que sum
peut recevoir des paramètres de n'importe quelle longueur. 🎜🎜Implémenter asyncAdd🎜asyncAdd
, encapsulez-la comme l'implémentation de Promise
, c'est-à-dire la fonction caculer
li>asyncAdd
ne peut en fait recevoir que deux nombres à la fois pour le calcul et utilise une boucle pour transmettre plusieurs paramètres séparémentasync/await
pour garantir la séquence d'exécution correcte, et la valeur de retour de la fonction async
correspond exactement à la somme
et est de les exigences de type Promesse
caculer
La fonction peut être extraite vers la couche externe de la fonction sum
asyncAdd
La fonction de rappel de la fonction n'a pas besoin d'être extraite car elle s'appuie sur trop de paramètres et de méthodes externes Multi total
, sum
est appelé deux fois, et Les paramètres sont toujours exactement les mêmes, et le but est de vous rappeler que lors du calcul du même contenu pour la deuxième fois, les résultats sont obtenus directement à partir du cache, plutôt que via un calcul asynchrone. 🎜rrreee🎜Ce qui suit n'est qu'une implémentation d'une solution de mise en cache simple. Ne vous inquiétez pas trop. L'implémentation spécifique est la suivante : 🎜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前端】
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!