Ich habe eine Klasse, die db-Methoden enthält und es ist in einem Proxy eingewickelt, der den Zugriff auf Eigenschaften behandelt. Da das Thema verspricht hier bezogen wird, ist ein vereinfachtes Beispiel-Code, der das gleiche Problem reproduziert:Versprechen als Klassenmethode Aufruf triggert object.then beim Auflösen
const handler = {
ownKeys(target) {
return Object.keys(target._attributes)
},
get(target, property) {
console.log(`<-${property}`) // <-- this logs what properties are being accessed
if (typeof target[property] !== 'undefined') {
return Reflect.get(target, property)
}
return Reflect.get(target._attributes, property)
},
set(target, property, value) {
target._attributes[property] = value
return true
}
}
class User {
static table = 'users'
static fetch(query = {}, opts = {}) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(new this(query))
}, 500)
})
}
constructor(attributes = {}) {
this._attributes = attributes
return new Proxy(this, handler)
}
}
async function trigger() {
const user = await User.fetch({test:'test'})
console.log(JSON.stringify(user._attributes))
}
trigger()
Alles funktioniert gut, während der Test ich einen Ausdruck an den Proxy hinzugefügt haben Performance-Einbußen der Verwendung eines solchen zu bestimmen, Modellentwurf, und ich bemerkte, dass mein Modell aus der Versprechungskette heraus aufgerufen wird.
Beispielausgabe folgt:
<-then
<-_attributes
{"test":"test"}
Ich denke, dass new this(query)
Rückkehr die Versprechungen verursacht vielleicht zu denken, dass es ein Versprechen zurück und folglich .then()
ausgeführt wird. einzige Lösung, die ich gefunden habe, ist, wie diese Entschlossenheit Antwort innerhalb neues Array oder ein anderes Objekt zu wickeln:
static fetch(query = {}, opts = {}) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve([new this(query)])
}, 500)
})
}
// Output
// 2
// <-_attributes
// {"test":"test"}
Was ich frage mich, ist dies richtige Weg, und es gibt auch andere Lösungen für diese Nebenwirkung?
Was genau stimmt nicht mit dem Verhalten, das Sie jetzt sehen? Der Wert, der an "resolve" übergeben wird, kann ein "thenable" sein, also prüft er, ob '.then 'existiert. Das wird erwartet. – loganfsmyth
Es ist nichts falsch, ich habe mich nur gefragt, ob dies erwartet Verhalten ist und es ist ein Weg um es herum. Das ist, dass ich unnötige Aufrufe an Proxy verhindern wollte, da seine Leistung in einigen Fällen fraglich ist. –
Die Lösung mit "*' new this (query) "bewirkt, dass die Versprechen zu denken, dass es vielleicht ein Versprechen zurückgegeben *" - ja, genau. "... und folglich' .then() 'wird ausgeführt *" - nein, es wird nicht ausgeführt, weil es nicht existiert. Aber es wird zugegriffen, um * es * zu versuchen, es auszuführen, falls es eine Methode ist. – Bergi