Cela peut ne jamais le travail.
L' async
mot-clé permet d' await
à être utilisé dans une fonction marquée async
, mais il convertit également cette fonction dans une promesse générateur. Donc une fonction marquée avec async
sera de retour d'une promesse. Un constructeur d'autre part renvoie à l'objet qu'il est en train de construire. Ainsi, nous avons une situation où vous voulez retourner un objet et une promesse: une situation impossible.
Vous ne pouvez utiliser async/await où vous pouvez utiliser des promesses, car ils sont essentiellement syntaxe de sucre pour des promesses. Vous ne pouvez pas utiliser des promesses dans un constructeur parce qu'un constructeur doit renvoyer l'objet à construire, pas une promesse.
Il existe deux modèles de conception pour surmonter cette difficulté, à la fois inventé avant promesses ont été autour.
-
L'utilisation d'un init()
fonction. Cela fonctionne un peu comme du jQuery .ready()
. L'objet que vous créez peut être utilisé uniquement à l'intérieur de sa propre init
ou ready
fonction de:
Utilisation:
var myObj = new myClass();
myObj.init(function() {
// inside here you can use myObj
});
Mise en œuvre:
class myClass {
constructor () {
}
init (callback) {
// do something async and call the callback:
callback.bind(this)();
}
}
-
L'utilisation d'un constructeur. Je n'ai pas vu ce très utilisée en javascript, mais c'est l'un des plus commun des solutions de rechange en Java lorsqu'un objet doit être construit de manière asynchrone. Bien sûr, le générateur de modèle est utilisé lors de la construction d'un objet qui nécessite beaucoup de compliqué paramètres. Ce qui est exactement le cas d'utilisation asynchrone constructeurs. La différence est que d'un générateur asynchrone ne renvoie pas à un objet, mais une promesse de cet objet:
Utilisation:
myClass.build().then(function(myObj) {
// myObj is returned by the promise,
// not by the constructor
// or builder
});
// with async/await:
async function foo () {
var myObj = await myClass.build();
}
Mise en œuvre:
class myClass {
constructor (async_param) {
if (typeof async_param === 'undefined') {
throw new Error('Cannot be called directly');
}
}
static build () {
return doSomeAsyncStuff()
.then(function(async_result){
return new myClass(async_result);
});
}
}
Mise en œuvre avec async/await:
class myClass {
constructor (async_param) {
if (typeof async_param === 'undefined') {
throw new Error('Cannot be called directly');
}
}
static async build () {
var async_result = await doSomeAsyncStuff();
return new myClass(async_result);
}
}
Remarque: bien que dans les exemples ci-dessus, nous utilisons des promesses pour le générateur asynchrone ils ne sont pas à proprement parler nécessaire. Vous pouvez tout aussi bien écrire un constructeur qui accepte un rappel.
Note sur les appels de fonctions à l'intérieur des fonctions statiques.
Cela n'a rien à voir avec async constructeurs, mais avec le mot-clé this
signifie réellement (qui peut être un peu surprenant, les personnes en provenance des langues qui n'automatique de la résolution de noms de méthode, qui est, les langues qui n'ont pas besoin de l' this
mot-clé).
L' this
mot-clé renvoie à l'objet instancié. Pas la classe. Par conséquent, vous ne peut normalement pas utiliser this
à l'intérieur des fonctions statiques puisque la fonction statique n'est lié à aucun objet, mais est liée directement à la classe.
C'est-à-dire, dans le code suivant:
class A {
static foo () {}
}
Vous ne pouvez pas faire:
var a = new A();
a.foo() // NOPE!!
au lieu de cela, vous devez l'appeler comme:
A.foo();
Par conséquent, le code suivant devrait en résulter une erreur:
class A {
static foo () {
this.bar(); // you are calling this as static
// so bar is undefinned
}
bar () {}
}
Pour corriger cela, vous pouvez faire bar
soit une fonction régulière ou d'une méthode statique:
function bar1 () {}
class A {
static foo () {
bar1(); // this is OK
A.bar2(); // this is OK
}
static bar2 () {}
}