控制台中的递归,批量计算(JS)



我有一个网站,可以计算音乐语调的各个方面。我想在控制台中进行批量计算,但递归似乎造成了问题,因为它需要运行一个函数(也许?(。我有一个很大的数组,叫做ratio,里面有很多分子和分母。我想将它们注入预先存在的变量inputNuminputDen中,然后运行我在网站上编码的底层JS函数doCalc(),该函数接受输入并对它们进行各种计算。结果输出到页面上的一些div字段中,我只想将其打印在日志中(复制并粘贴到电子表格中(。到目前为止,在定义了大的分数数组ratio之后,我的代码看起来是这样的。

var i = 0;                  
async function loop() {   
inputNum = ratio[i][0];
inputDen = ratio[i][1];
await doCalc();       
console.log(document.getElementById("notationOutput").innerHTML+" "+document.getElementById("noteName").innerHTML);   
i++;                   
if (i < ratio.length) {           
loop();             
}                      
}
loop(); 

由于在显示结果之前进行计算需要花费不可忽略的时间(我认为(,我认为异步函数是可行的,但我似乎没有正确实现它。否则,我会用一个简单的while循环来完成,但显然setTimeout在这种情况下不起作用。

正如评论中所讨论的,您想要做的事情应该是可能的,但这是编写此类功能的一种非常糟糕的方式。依赖DOM和全局变量来完成工作是非常令人讨厌的。

如果我们从这样的东西开始:

const doCalc = () => {
const num = Number (document .getElementById ('numerator') .value)
const den = Number (document .getElementById ('denominator') .value)
// do some real work here
const notationOutput = `${num}/${den}`
const noteName = `${num}--${den}`
document .getElementById ("notationOutput") .innerHTML = notationOutput
document .getElementById ("noteName") .innerHTML = noteName
}
document .getElementById ('numerator') .onchange = doCalc
document .getElementById ('denominator') .onchange = doCalc
const logAll = (ratios) =>
ratios 
.forEach (([num, den]) => {
document .getElementById ('numerator') .value = String (num)
document .getElementById ('denominator') .value = String (den)
doCalc()
const notationOutput = document .getElementById ("notationOutput") .innerHTML
const noteName = document .getElementById ("noteName") .innerHTML
console.log(`${notationOutput} ${noteName}`)
})
const ratios = [[5, 3], [7, 4], [3, 2], [13, 1]]
document.getElementById('batch') .onclick = (evt) => logAll (ratios)
<p>
<label>Numerator: <input id="numerator" /></label>
<label>Denominator: <input id="denominator" /></lbael>
</p>
<p>Notation Output <span id="notationOutput"></span></p>
<p>Note Name <span id="noteName"></span></p>
<p><button id="batch">Run Batch</button></p>


我们最终会想要这样的东西:

const doCalc = ([num, den]) => {
// do some real work here
return {
notationOutput: `${num}/${den}`,
noteName: `${num}--${den}`
}
}
const change = (evt) => {
const num = Number (document .getElementById ('numerator') .value)
const den = Number (document .getElementById ('denominator') .value)
const {notationOutput, noteName} = doCalc ([num, den])
document .getElementById ("notationOutput") .innerHTML = notationOutput
document .getElementById ("noteName") .innerHTML = noteName
}
document .getElementById ('numerator') .onchange = change
document .getElementById ('denominator') .onchange = change
const logAll = (ratios) =>
ratios 
.map (doCalc) 
.forEach (
({notationOutput, noteName}) => console.log(`${notationOutput} ${noteName}`)
)
const ratios = [[5, 3], [7, 4], [3, 2], [13, 1]]
document.getElementById('batch') .onclick = (evt) => logAll (ratios)
<p>
<label>Numerator: <input id="numerator" /></label>
<label>Denominator: <input id="denominator" /></lbael>
</p>
<p>Notation Output <span id="notationOutput"></span></p>
<p>Note Name <span id="noteName"></span></p>
<p><button id="batch">Run Batch</button></p>

最大的区别在于,计算是在不担心DOM的情况下完成的。它是一个纯函数,使用它的代码可以使用它来写入控制台或更新DOM。


不过,请注意,我的第一个块确实有效。如果你把循环改成这种结构,它可能对你有用。但它将永远是难以测试、难以扩展和难以理解的代码。

第二种格式要简单得多。

您是否尝试将await添加到loop((调用中,该调用在if内部调用,如下所示

var i = 0;                  
async function loop() {   
inputNum = ratio[i][0];
inputDen = ratio[i][1];
await doCalc();       
console.log(document.getElementById("notationOutput").innerHTML+" "+document.getElementById("noteName").innerHTML);   
i++;                   
if (i < ratio.length) {           
await loop();  // Adding await here           
}                      
}
loop(); 

(或(

作为一个自调用调用

(async function loop() {   
inputNum = ratio[i][0];
inputDen = ratio[i][1];
await doCalc();       
console.log(document.getElementById("notationOutput").innerHTML+" "+document.getElementById("noteName").innerHTML);   
i++;                   
if (i < ratio.length) {           
await loop();  // Adding await here           
}                      
})();

类似的示例供您参考-滚动到async/await递归示例函数的末尾。

最新更新