TypeScript 在Mobile Safari上超过最大堆栈大小 翻译结果:在Mobile Safari上超过最大堆栈大小

hts6caw3  于 5个月前  发布在  TypeScript
关注(0)|答案(3)|浏览(45)

搜索词:

最大堆栈大小,堆栈
Typescript版本:
3.9.2

代码

import * as dom from "react-dom-factories";
import { NominalType } from "Framework/NominalType";

export abstract class HTML {
    protected nominal: NominalType;

    constructor() {
        throw new Error("Construct HTML using HTML.fromString()");
    }

    // Expose method from actual runtime String class.
    abstract toString(): string;

    static fromString(value: string): HTML {
        return <any>value;
    }

    static toString(value: HTML): string {
        return <any>value;
    }

    static renderInlineFromString(value: string) {
        return HTML.renderInline(HTML.fromString(value));
    }

    static renderInline(value: HTML) {
        var html = HTML.toString(value);
        if (_.isString(html)) {
            return dom.span({ dangerouslySetInnerHTML: { __html: html } });
        } else {
            return null;
        }
    }

    static renderBlock(value: HTML) {
        var html = HTML.toString(value);
        if (_.isString(html)) {
            return dom.div({ dangerouslySetInnerHTML: { __html: html } });
        } else {
            return null;
        }
    }
}

生成的代码(作为我们的--outFile构建的一部分,用于此模块):

define("App/Data/HTML", ["require", "exports", "react-dom-factories"], function (require, exports, dom) {
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    exports.HTML = void 0;
    var HTML = /** @class */ (function () {
        function HTML() {
            throw new Error("Construct HTML using HTML.fromString()");
        }
        HTML.fromString = function (value) {
            return value;
        };
        HTML.toString = function (value) {
            return value;
        };
        HTML.renderInlineFromString = function (value) {
            return HTML.renderInline(HTML.fromString(value));
        };
        HTML.renderInline = function (value) {
            var html = HTML.toString(value);
            if (_.isString(html)) {
                return dom.span({ dangerouslySetInnerHTML: { __html: html } });
            }
            else {
                return null;
            }
        };
        HTML.renderBlock = function (value) {
            var html = HTML.toString(value);
            if (_.isString(html)) {
                return dom.div({ dangerouslySetInnerHTML: { __html: html } });
            }
            else {
                return null;
            }
        };
        return HTML;
    }());
    exports.HTML = HTML;
});

预期行为:

AMD模块无论有多少导出,都不会耗尽堆栈空间。

实际行为:

每个导出的函数或类都会消耗堆栈空间。
关键问题是Typescript导出的代码生成为每个导出生成一个局部变量。因此,如果您有数千个导出,生成的代码会崩溃一些浏览器(在我们的情况下,是移动Safari)。这是由于我们服务器端接口生成的代码所导致的。
对于AMD模块的导出函数,如果没有在本地引用,就不应该消耗局部堆栈空间。最好的做法是,本地引用也通过导出来节省堆栈空间。

相关问题:

与堆栈大小相关的其他问题涉及到编译器本身耗尽其自身的堆栈,而不是生成耗尽堆栈的代码。

kxe2p93d

kxe2p93d1#

Safari那边有没有提交bug?我想他们应该希望浏览器能对这种事情进行加固。

kqlmhetl

kqlmhetl2#

在这里,"正确的"发射是什么?

y3bcpkx1

y3bcpkx13#

我猜在Safari这边,这可能不是一个bug,因为他们有一个栈限制,而JS局部变量消耗栈限制似乎是合理的。
至于“正确的”发射,它可能是这样的:

define("App/Data/HTML", ["require", "exports", "react-dom-factories"], function (require, exports, dom) {
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    exports.HTML = void 0;
    exports.HTML = /** @class */ (function () {
        function HTML() {
            throw new Error("Construct HTML using HTML.fromString()");
        }
        HTML.fromString = function (value) {
            return value;
        };
        HTML.toString = function (value) {
            return value;
        };
        HTML.renderInlineFromString = function (value) {
            return HTML.renderInline(HTML.fromString(value));
        };
        HTML.renderInline = function (value) {
            var html = HTML.toString(value);
            if (_.isString(html)) {
                return dom.span({ dangerouslySetInnerHTML: { __html: html } });
            }
            else {
                return null;
            }
        };
        HTML.renderBlock = function (value) {
            var html = HTML.toString(value);
            if (_.isString(html)) {
                return dom.div({ dangerouslySetInnerHTML: { __html: html } });
            }
            else {
                return null;
            }
        };
        return HTML;
    }());
});

基本上是相同的,但立即分配导出而不是存储一个局部变量。

相关问题