2016-11-25 2 views
0

Ich möchte mehrere asynchrone Aufgabe mit Async-Paket ausführen. Aber ich habe Probleme mit JavaScript-Prototypen zugreifen."this" zurück undefined in einer Prototyp-Funktion

Hier ist die Probe meiner Code:

var env = function(options) { 
 
    this.options = options; 
 
} 
 

 
env.prototype.run = function() { 
 
    
 
    var self = this, 
 
    async.series([ 
 
    self.task1, 
 
    self.task2 
 
    ], function done(responses) { 
 
     console.log(responses); 
 
    }); 
 
} 
 

 

 
env.prototype.task1 = function() { 
 
    console.log(this.options); // undefined 
 
    // logic code... 
 
} 
 

 

 

 
var foo = new env({foo: 'bar'}); 
 
foo.run(); // undefined - from console.log

Sie wissen nicht, warum ich nicht die 'this' Eigenschaften meines Object Dieser Code

+1

Press th'Run Code snippet' Taste und siehe 'Uncaught Syntaxerror: unerwartete token' – GillesC

+1

Stapel Snippets sind für ** runnable ** Beispiele, aber die oben ist nicht ausführbar. Ein ausführbares Beispiel ist sehr nützlich, da es sicherstellt, dass Sie wichtige Informationen nicht ausgelassen haben und dass die Leute das Problem sehen können. Es macht es auch für die Menschen einfach, Ihnen einen funktionierenden Fix zu zeigen. Wenn Sie es nicht runnable machen wollen, benutzen Sie einfach einen Codeblock (den '{}' Toolbar-Button), aber ich ermutige Sie, Snippets weiter zu verwenden - machen Sie sie einfach runnable. –

+0

Ich habe gerade festgestellt, dass, während die Präsentation ein wenig anders als die üblichen ist, im Grunde ist dies ein Duplikat der Frage, die ich gerade verknüpft habe. Hoffentlich hilft diese Frage anderen, die 'async.series' verwenden, die das gleiche Problem haben. –

Antwort

1

zugreifen

async.series([ 
    self.task1, 
    self.task2 
], function done(responses) { 
    console.log(responses); 
}); 

übergibt nur Funktionsreferenzen an async.series, aber tut nichts, um sicherzustellen, dass this korrekt ist, wenn sie aufgerufen werden.

Es sei denn, die async.series Sie verwenden bietet einen Weg, es zu sagen, welche this zu verwenden, können Sie leicht lösen das Problem mit bind:

async.series([ 
    self.task1.bind(self),  // *** 
    self.task2.bind(self)   // *** 
], function done(responses) { 
    console.log(responses); 
}); 

hier ein einfacheres Beispiel demonstriert das Problem und Lösung:

var obj = { 
 
    property: "testing", 
 
    wrong: function() { 
 
    setTimeout(this.task1, 10); 
 
    }, 
 
    right: function() { 
 
    setTimeout(this.task1.bind(this), 20); 
 
    }, 
 
    task1: function() { 
 
    console.log("task1 says the property is " + this.property); 
 
    } 
 
}; 
 

 
obj.wrong(); 
 
obj.right();


Randbemerkung: Es sei denn, Sie self für etwas verwenden Sie nicht innerhalb run gezeigt haben, müssen Sie es nicht brauchen:

env.prototype.run = function() { 
    async.series([ 
    this.task1.bind(this), 
    this.task2.bind(this) 
    ], function done(responses) { 
     console.log(responses); 
    }); 
}; 

Eine weitere Option, wenn Sie ein ES2015-kompatible Umgebung verwenden (oder transpiling) Ihre Aufgaben in Pfeil Funktionen wickeln:

// Requres ES2015 support 
env.prototype.run = function() { 
    async.series([ 
    (...args) => this.task1(...args), 
    (...args) => this.task2(...args) 
    ], function done(responses) { 
     console.log(responses); 
    }); 
}; 
+0

Aber in diesem Beispielcode sah ich, dass ** das ** bezieht sich auf die richtige ** task1 ** -Funktion, weil ich eine Ausgabe Nachricht von meinem console.log() –

+0

@SimonBruneaud: Ja, die richtige * Funktion *. Aber die Funktion wird * mit dem falschen Wert für 'this' aufgerufen. –

+0

Aber die Bindung machen die console.log arbeiten, danke. Ich lese ein bisschen mehr über diese ** Bind ** Funktion –

Verwandte Themen