In my typescript proyect I have a Configuration and a Controller class:
class Config {
public Ready: Promise<any>;
private logDir: string = 'dir1';
private logFile: string = 'file1';
private client = new Etcd3();
constructor(defaultLogDir?: string, defaultLogFile?: string){
this.Ready = new Promise((resolve, reject) => {
this.readLogDir().then(res => { this.logDir = res; });
this.readLogFile().then(res => { this.logFile = res; });
resolve(undefined);
})
}
}
class Controller {
public Ready: Promise<any>;
public config: Config = new Config();
private logDir: string = 'dir2';
private logFile: string = 'file2';
constructor(){
this.Ready = new Promise((resolve, reject) => {
this.config.Ready.then(() => {
this.logDir = this.config.getLogDir();
this.logFile = this.config.getLogFile();
resolve(undefined);
})
})
}
}
Since the Configuration class has to work with I/O and server connections a promise is used(Ready) to determine when the class is usable, therefore, the class is always called as follows: config.then(() => {code})
. This way of working is tested and is behaving correctly isolated.
Now, the Controller class works the same way and, thus, when it's rightfully called: controller.then(() => {code})
, it should imply that the Config object is also ready but this is not the case since the values of the controller atributes are dir2 and file2.
What is wrong in my reasoning or my code?
CodePudding user response:
new Promise((resolve, reject) => {
this.readLogDir().then(res => { this.logDir = res; });
this.readLogFile().then(res => { this.logFile = res; });
resolve(undefined);
})
This creates a new promise which kicks off some async stuff and then immediately resolves to undefined. You are not waiting for anything before you call resolve
.
Since you already have promises on hand, you don't need to use the new Promise
constructor at all. That constructor is only really needed when you're converting something that doesn't use promises into something that does. You can create two promises for reading the logDir and logFile, and then use Promise.all
to combine them:
this.ready = Promise.all([
this.readLogDir().then(res => { this.logDir = res; }),
this.readLogFile().then(res => { this.logFile = res; })
]);
CodePudding user response:
I notice the title in OP's post is about promising chaining. Note that node.js is asynchronous, and in the given implementation, these two promises are executed simultaneously. See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises#chaining
this.readLogDir().then(res => {
this.logDir = res;
this.readLogFile().then(res => { this.logFile = res; });
});
example for chaining ^