I'm using JavaScript classes to write a small tool for work. I don't like callbacks nesting and nesting, so I like to break them out into separate functions. I'm trying to run requests, which take a callback, from within a for...of loop. The problem is, when I break the callback out into a separate function, it looses the scope of the for...in loop and it doesn't know what "service.url" is.
Here is my code:
const DATA = require("../resources/data.json");
const Request = require("request");
class Net {
constructor(){}
_handleResponses(e, r, b) {
console.log("--------------------------------------------------------------");
if(r.statusCode == 404) {
console.log("\x1b[31m"+`[RESPONSE](Status ${r.statusCode})`, "\x1b[0m");
console.log("\x1b[31m"+`Server: ${service.server}`, "\x1b[0m");
console.log("\x1b[31m"+`Service: ${service.service}`, "\x1b[0m");
console.log("\x1b[31m"+`Body: ${b}`, "\x1b[0m");
} else {
console.log(`[RESPONSE](Status ${r.statusCode})`);
console.log(`Server: ${service.server}`);
console.log(`Service: ${service.service}`);
console.log(`Body: ${b}`);
}
}
pollServices() {
for(let service of DATA) {
Request(service.url, this._handleResponses);
}
}
}
module.exports = Net;
Here is the error I get when the "pollServices" function/method runs:
C:\\Users\\payton.juneau\\Desktop\\Me\\Projects\\Node\\com.etouchmenu.tools.crystalBall\\utilities\\net.js:17 console.log(
Server: ${service.server}
); ^ReferenceError: service is not defined at Request._handleResponses [as _callback] (C:\\Users\\payton.juneau\\Desktop\\Me\\Projects\\Node\\com.etouchmenu.tools.crystalBall\\utilities\\net.js:17:36) at Request.self.callback (C:\\Users\\payton.juneau\\Desktop\\Me\\Projects\\Node\\com.etouchmenu.tools.crystalBall\\node_modules\\request\\request.js:186:22) at Request.emit (events.js:159:13) at Request. (C:\\Users\\payton.juneau\\Desktop\\Me\\Projects\\Node\\com.etouchmenu.tools.crystalBall\\node_modules\\request\\request.js:1163:10) at Request.emit (events.js:159:13) at IncomingMessage. (C:\\Users\\payton.juneau\\Desktop\\Me\\Projects\\Node\\com.etouchmenu.tools.crystalBall\\node_modules\\request\\request.js:1085:12) at Object.onceWrapper (events.js:254:19) at IncomingMessage.emit (events.js:164:20) at endReadableNT (_stream_readable.js:1062:12) at process._tickCallback (internal/process/next_tick.js:152:19)
Any help would be much appreciated, kind of new to all of this type of stuff..
When you define 2 methods on a class, they each create their own independent scope:
class Example {
method1() {
// scope of method 1 only visible to method 1
let hiddenInM1 = 'example'; // <-- only available here
}
method2() {
// scope of method 2 only visible to method 2
// I don't know what m1 is
}
}
There are 3 ways for these methods to share values with each other.
1. Using a variable available in an outer scope in which both of these methods belong to:
let sharedGlobal = 'example';
class Example {
method1() {
// I can see sharedGlobal
}
method2() {
// I also can see sharedGlobal
}
}
This is usually ill-advised because global state is prone to bugs .
2. Through the context of the class those methods belong to (via this
)
class Example {
constructor() {
this.sharedClassVar = 'example'
}
method1() {
// I can see this.sharedClassVar
}
method2() {
// I also can see this.sharedClassVar
}
}
3. By passing arguments to each other.
class Example {
method1(fromMethod2) {
// I can receive stuff from method2
}
method2() {
this.method1('example')
}
}
If you look at your code, none of these patterns are present and thus _handleResponses
doesn't have access to the service
defined in pollServices
.
The easiest change you can make is to pass the service
yourself:
_handleResponses(service, e, r, b) {
// ^^^^^^^ receive the service here
}
pollServices() {
for (let service of DATA) {
Request(service.url, (...args) => this._handleResponses(service, ...args))
// ^^^^^^^ pass the service with the args
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.