JavaScript字符串相等似乎偶尔在Chrome中被打破,可能与Web Workers有关?

gorkyyrv  于 9个月前  发布在  Go
关注(0)|答案(1)|浏览(101)

我的应用程序中有一个函数,(对于一小部分用户,但每天都有少数人)引发一个似乎不可能的错误。从函数引发的错误来看,它看起来像'center' !== 'center'。每次发生此错误都发生在Chrome上,第一次发生在2023年10月16日。用户遇到此错误一两次,然后它似乎自己解决了。
下面是该函数的简化版本。去掉了很多代码,但相关的控制流几乎完全相同。

function createBaseGradient(gradient) {
    const start = gradient.start;
    
    // ...

    if (start === 'center') {
        // ...
        return '...'
    }

    // ...

    if (start === 'left') {
        // ...
    } else if (start === 'top') {
        // ...
    } else if (start === 'bottom') {
        // ...
    } else if (start === 'right') {
        // ...
    } else {
        internalError(
            `Illegal gradient start (${JSON.stringify(start)}, ${encodeURIComponent(
                start
            )}, ${stringToCharCodes(
                start
            )}) of type ${typeof start}. Webworker: ${isWebWorker}. Valid gradient starts are: (${VALID_STARTS}, ${VALID_STARTS.map(
                stringToCharCodes
            )})`
        );
    }

    // ...

    return '...';
}

字符串
下面是我看到的一个错误的确切文本:
错误:非法梯度开始(“center”,center,99,101,110,116,101,114,END)类型字符串。Webworker:false。有效的渐变开始是:(中心,左上,左,左下,上,下,右上,右,右下,99,101,110,116,101,114,结束,108,101,102,116,45,116,111,112,结束,108,101,102,116、END、108、101、102、116、45、98、111、116、116、111、109、END、116、111、112、END、98、111、116、116、111、109、END、114、105、103、104、116、45、116、111、112、END、114、105、103、104、116、END、114、105、103、104、116、END、114、105、103、104、116、45、98、111、116、116、111、109,结束)
因此,常量start是一个字符串,值为"center",字符串中的所有字符都与字符串"center"中的字符相同,顺序相同。但是start === 'center'不可能为真,因为我们没有输入第一个if语句并返回。
一些可能相关的细节:参数gradient在此函数中使用之前在web worker中创建。gradient.start从Brython字符串类型转换为JavaScript字符串。start的其他值确实会发生此错误。
以下是我迄今为止尝试的方法:我添加了上面包含的详细日志记录。我尝试将函数中的所有字符串存储在常量中,并使用这些常量创建VALID_STARTS数组,以防某些浏览器扩展修改字符串,但情况似乎并非如此。我添加了更多日志记录,上面没有包含,抛出一个错误,如果我们以某种方式进入start === 'center'的情况下,并继续没有返回,但该错误从来没有触发。
我还尝试创建一个可能的Web Worker错误的最小示例(其中从Web Worker发布的字符串'abc'可能不等于'abc')。我在我的计算机上运行了几百万次,但它从未产生过错误。第一个错误的日期与新的Chrome版本或我这端的任何相关部署不一致。我简要地浏览了Chrome中的开放错误,但看起来我在那里不会有好运。
我真的很感激听到关于如何解决这个bug的新观点,以及来自任何JS大师的见解。这个字符串可能不是字符串,尽管'string'typeof start?我可能不小心修改了字符串原型并以某种方式打破了平等?我不知道下一步该看哪里。
这里有一个链接到这个函数的未经编辑的源代码,如果它会有帮助的话:https://pastebin.com/0hdqLjqH
非常感谢你的任何想法!

基于评论中建议的新信息:

我在if (start == 'center') if语句之前记录了以下值。它们的结果在值旁边的注解中。

const a = start + '!'; // center!
const b = CENTER + '!!'; // center!!
const f = start == CENTER; // false
const c = start === CENTER; // false
const d = typeof start; // string
const e = start.toString() === CENTER.toString(); // true
const g = start.normalize('NFC') === CENTER.normalize('NFC'); // true


所以有进步!我还不清楚为什么调用.toString()会有不同,或者当我们已经比较了每个字符代码时,规范化字符串会有什么不同,但我们现在实际上有一些事情要做。

czfnxgou

czfnxgou1#

这段代码看起来甚至不正确。变量不能和常量是同一个对象=。但是变量可以等于常量==。

var start = prompt("please input one of 'left', 'right', 'bottom', 'top'");
    if (start === 'left') {
      alert("your input was 'left'");
    } else if (start === 'top') {
      alert("your input was 'top'");
    } else if (start === 'bottom') {
      alert("your input was 'bottom'");
    } else if (start === 'right') {
      alert("your input was 'right'");
    } else {
      alert("your input was none of the known options");
    }

字符串

相关问题