Vue.js中按概率从对象数组抽取随机元素的实现与问题排查
问题根因&修复方案
按出现概率从高到低整理问题原因和对应修复方法:
1. Promise静默吞错 + 调用指向错误
你在.then回调中用this.second_function调用方法,但你定义second_function用的是普通全局函数声明,若当前代码上下文的this不是全局对象(比如代码位于类方法、模块作用域内),this.second_function实际不存在,调用时会抛出错误。而Promise回调中的错误默认会被静默吞噬,不会打印到控制台,所以你只能看到第一次碰巧调用成功的输出。
如果你的second_function确实是挂载在当前this上的方法(比如类实例方法),也可以通过加catch的方式看到具体报错信息。
修复代码:
my_promise.then((result) => { // 数组遍历不要用for...in,换for...of避免遍历到非预期属性 for (const pullArr of result) { // 如果是全局函数直接调用,不需要加this second_function(pullArr); // 如果确实是this上的方法就保留this.,加catch看报错即可 // this.second_function(pullArr); } }).catch(err => { // 捕获Promise内部错误,避免吞错 console.error('执行出错:', err); });
2. 子数组权重总和不足100
second_function的现有逻辑仅在权重累加和大于随机值时输出日志,如果某一个子数组的cardRatio累加总和小于100,一旦生成的随机值大于总和,就不会命中任何判断分支,自然不会有输出。
修复代码:
function second_function(pull) { const winner = Math.random() * 100; let threshold = 0; for (let i = 0; i < pull.length; i++) { threshold += pull[i].cardRatio; if (threshold > winner) { console.log("winner", pull[i]); return; } } // 加兜底逻辑,总和不足100时默认返回最后一张卡 console.log("winner", pull[pull.length - 1]); }
3. for...in遍历拿到非预期元素
for...in是为遍历对象可枚举属性设计的,不适合数组遍历,如果你之前给Array.prototype添加过自定义属性,for...in会遍历到这些额外属性,传入second_function的参数不合法,就不会产生输出。
替换成for...of或者普通下标for循环就能解决,就是第一种修复方案里的写法。
内容的提问来源于stack exchange,提问作者François Biscuit
相关产品推荐
相关产品推荐

