JavaScript点击事件绑定随机文本时await报错问题及修正代码验证
先直接给你结论:你更新后的代码已经正确解决了最初的报错问题,核心逻辑是可以正常运行的!不过里面有几个小细节可以优化,我给你一步步拆解:
最初报错的原因
你一开始遇到的"await can only be used on async function"错误,根源很简单:
await关键字必须在标记为async的函数内部使用- 你最初给
addEventListener传的点击回调是普通箭头函数:() => {...},没有加async修饰,所以在里面用await createRandomShit()就会触发语法错误
你更新后的代码为什么能工作?
你把点击回调改成了async () => {...},这就满足了await的使用条件——现在这个回调函数是异步函数了,所以await可以正常调用createRandomShit()这个异步函数(虽然它里面其实没有真正的异步操作,但标记为async也没问题)。
另外你把createRandomShit里的console.log(masterReturn)移到了return之后,这里要注意:return语句之后的代码永远不会执行,所以这个console.log是无效的,你如果需要打印生成的随机文本,应该把它放在return之前。
几个可以优化的小细节
- 循环方式优化:你用
[...Array(overallTimes)].map(...)来循环,但map的作用是生成新数组,你这里只是用来做累加操作,完全没必要生成中间数组,用普通的for循环或者for...of循环更高效:
const createRandomShit = async() => { const overallTimes = getRandomInt(50, 500) let masterReturn = ''; // 换成for循环更高效 for (let i = 0; i < overallTimes; i++) { let randIndex = getRandomInt(0, alphabet.length) masterReturn += alphabet[randIndex] } console.log(masterReturn) // 放在return前面才能执行 return masterReturn }
随机索引范围修正:你的
alphabet数组有26个字母(索引0到25),但你之前用getRandomInt(1,24),只能取到索引1到23的字母,会漏掉第一个字母a和最后几个字母(比如w、y、z)。改成getRandomInt(0, alphabet.length)就能覆盖所有字母了。异步函数的必要性:其实
createRandomShit里面没有任何真正的异步操作(比如网络请求、定时器),所以它没必要标记为async,直接改成普通函数也能正常工作,这样调用的时候甚至可以不用await(不过用了也不影响):
// 改成普通函数 const createRandomShit = () => { const overallTimes = getRandomInt(50, 500) let masterReturn = ''; for (let i = 0; i < overallTimes; i++) { let randIndex = getRandomInt(0, alphabet.length) masterReturn += alphabet[randIndex] } console.log(masterReturn) return masterReturn } // 回调里可以不用await,直接赋值 c.forEach(ch => { ch.addEventListener('click', () => { contentShowOutput.textContent = '' let j = createRandomShit() console.log("j", j) contentShowOutput.textContent = 'testing... ' + j }) })
总的来说,你更新后的代码已经解决了核心问题,只要把那个无效的console.log调整位置,再优化下循环和随机范围,就更完美了!
内容的提问来源于stack exchange,提问作者java script

