Skip to content

Commit f555c43

Browse files
authored
fix: Request execution time keeps increasing over time when using Parse.Object.extend (#1682)
1 parent c63e738 commit f555c43

File tree

2 files changed

+55
-23
lines changed

2 files changed

+55
-23
lines changed

src/ParseObject.js

Lines changed: 37 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1959,37 +1959,60 @@ class ParseObject {
19591959
let parentProto = ParseObject.prototype;
19601960
if (this.hasOwnProperty('__super__') && this.__super__) {
19611961
parentProto = this.prototype;
1962-
} else if (classMap[adjustedClassName]) {
1963-
parentProto = classMap[adjustedClassName].prototype;
19641962
}
1965-
const ParseObjectSubclass = function (attributes, options) {
1963+
let ParseObjectSubclass = function (attributes, options) {
19661964
this.className = adjustedClassName;
19671965
this._objCount = objectCount++;
19681966
// Enable legacy initializers
19691967
if (typeof this.initialize === 'function') {
19701968
this.initialize.apply(this, arguments);
19711969
}
19721970

1971+
if (this._initializers) {
1972+
for (const initializer of this._initializers) {
1973+
initializer.apply(this, arguments);
1974+
}
1975+
}
1976+
19731977
if (attributes && typeof attributes === 'object') {
19741978
if (!this.set(attributes || {}, options)) {
19751979
throw new Error("Can't create an invalid Parse Object");
19761980
}
19771981
}
19781982
};
1979-
ParseObjectSubclass.className = adjustedClassName;
1980-
ParseObjectSubclass.__super__ = parentProto;
1981-
1982-
ParseObjectSubclass.prototype = Object.create(parentProto, {
1983-
constructor: {
1984-
value: ParseObjectSubclass,
1985-
enumerable: false,
1986-
writable: true,
1987-
configurable: true,
1988-
},
1989-
});
1983+
if (classMap[adjustedClassName]) {
1984+
ParseObjectSubclass = classMap[adjustedClassName];
1985+
} else {
1986+
ParseObjectSubclass.extend = function (name, protoProps, classProps) {
1987+
if (typeof name === 'string') {
1988+
return ParseObject.extend.call(ParseObjectSubclass, name, protoProps, classProps);
1989+
}
1990+
return ParseObject.extend.call(ParseObjectSubclass, adjustedClassName, name, protoProps);
1991+
};
1992+
ParseObjectSubclass.createWithoutData = ParseObject.createWithoutData;
1993+
ParseObjectSubclass.className = adjustedClassName;
1994+
ParseObjectSubclass.__super__ = parentProto;
1995+
ParseObjectSubclass.prototype = Object.create(parentProto, {
1996+
constructor: {
1997+
value: ParseObjectSubclass,
1998+
enumerable: false,
1999+
writable: true,
2000+
configurable: true,
2001+
},
2002+
});
2003+
}
19902004

19912005
if (protoProps) {
19922006
for (const prop in protoProps) {
2007+
if (prop === 'initialize') {
2008+
Object.defineProperty(ParseObjectSubclass.prototype, '_initializers', {
2009+
value: [...(ParseObjectSubclass.prototype._initializers || []), protoProps[prop]],
2010+
enumerable: false,
2011+
writable: true,
2012+
configurable: true,
2013+
});
2014+
continue;
2015+
}
19932016
if (prop !== 'className') {
19942017
Object.defineProperty(ParseObjectSubclass.prototype, prop, {
19952018
value: protoProps[prop],
@@ -2013,15 +2036,6 @@ class ParseObject {
20132036
}
20142037
}
20152038
}
2016-
2017-
ParseObjectSubclass.extend = function (name, protoProps, classProps) {
2018-
if (typeof name === 'string') {
2019-
return ParseObject.extend.call(ParseObjectSubclass, name, protoProps, classProps);
2020-
}
2021-
return ParseObject.extend.call(ParseObjectSubclass, adjustedClassName, name, protoProps);
2022-
};
2023-
ParseObjectSubclass.createWithoutData = ParseObject.createWithoutData;
2024-
20252039
classMap[adjustedClassName] = ParseObjectSubclass;
20262040
return ParseObjectSubclass;
20272041
}

src/__tests__/ParseObject-test.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3516,6 +3516,24 @@ describe('ParseObject extensions', () => {
35163516
ParseObject.enableSingleInstance();
35173517
});
35183518

3519+
it('can extend object', () => {
3520+
const startExtend = Date.now();
3521+
for (let i = 0; i < 100000; i++) {
3522+
// eslint-disable-next-line
3523+
const Parent = ParseObject.extend('Parent');
3524+
// eslint-disable-next-line
3525+
const parent = new Parent();
3526+
}
3527+
expect(Date.now() - startExtend).toBeLessThan(200);
3528+
3529+
const startNew = Date.now();
3530+
for (let i = 0; i < 100000; i++) {
3531+
// eslint-disable-next-line
3532+
const parent = new ParseObject('Parent');
3533+
}
3534+
expect(Date.now() - startNew).toBeLessThan(200);
3535+
});
3536+
35193537
it('can generate ParseObjects with a default className', () => {
35203538
const YourObject = ParseObject.extend('YourObject');
35213539
const yo = new YourObject();

0 commit comments

Comments
 (0)