控制台递归,批量计算(JS)
Recursion in console, batch calculation (JS)
我有一个网站可以计算音乐语调的各个方面。我想在控制台中进行批量计算,但递归似乎导致了问题,因为它需要 运行 一个函数(也许?)。我有一个名为 ratio
的非常大的数组,其中包含许多分子和分母。我想将它们注入到名为 inputNum
和 inputDen
的预先存在的变量中,然后是 运行 我在网站上编写的底层 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
在那种情况下不起作用。
您是否尝试过将 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
}
})();
your reference 的类似示例 - 滚动到 async
/await
递归 示例函数的末尾。
正如评论中所讨论的那样,你想做的事情应该是可能的,但这是编写此类功能的一种非常糟糕的方式。依靠 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.
另请注意,我的第一个块确实有效。如果您将循环更改为这种结构,它可能对您有用。但它会永远保持代码难以测试、难以扩展和难以理解。
第二种格式就简单多了。
我有一个网站可以计算音乐语调的各个方面。我想在控制台中进行批量计算,但递归似乎导致了问题,因为它需要 运行 一个函数(也许?)。我有一个名为 ratio
的非常大的数组,其中包含许多分子和分母。我想将它们注入到名为 inputNum
和 inputDen
的预先存在的变量中,然后是 运行 我在网站上编写的底层 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
在那种情况下不起作用。
您是否尝试过将 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
}
})();
your reference 的类似示例 - 滚动到 async
/await
递归 示例函数的末尾。
正如评论中所讨论的那样,你想做的事情应该是可能的,但这是编写此类功能的一种非常糟糕的方式。依靠 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.
另请注意,我的第一个块确实有效。如果您将循环更改为这种结构,它可能对您有用。但它会永远保持代码难以测试、难以扩展和难以理解。
第二种格式就简单多了。