来自PHP的深厚背景,我正在努力处理node / js的某些方面。
const ldap = require('ldapjs');
class LdapClient {
constructor({
url,
}) {
this.isBound = null;
this.client = ldap.createClient({ url });
}
authenticate(credentials) {
const _this = this;
return new Promise((resolve, reject) => {
return this.client.bind(credentials.username, credentials.password, (err, res) => {
if (err) {
this.client.unbind();
return reject(err);
}
_this.isBound = true;
return resolve(res);
});
});
}
}
const client = new Client({url: ''})
const credentials = {
'username': '',
'password': ''
}
client.authenticate(credentials)
.then(() => {
console.log('authenticated');
console.log('race = ' + client.isBound); // SHOWS TRUE
})
.catch(e => {
console.log(e);
})
console.log(client.isBound); // SHOWS NULL... WANT TRUE (RACE ISSUE as consoles before PROMISE)
我正在尝试访问Promise返回值之外的isBound
属性,该属性在成功的身份验证方法中被设置为true。
但是您看到的似乎是可能的比赛状况?
有没有办法解决这个问题...
谢谢
答案 0 :(得分:3)
这不是比赛条件。一切正常。您的代码中有两个console.logs
。第一个在承诺中,另一个在承诺之外。
您的调用进入异步模式,最后一个console.log
作为下一个命令按顺序执行,当时该变量的值为null
。您的变量稍后将使用正确的值进行解析。
如果您必须执行进一步的操作,则必须在.then()
方法的Client
部分中执行此操作,该方法仅在您的Promise
解决后才能执行。
例如
Client().then() {//all of your post response related logic should be here}
答案 1 :(得分:1)
因此您误解了关于诺言的某些事情。它们应用于异步代码,如下所示:
let p = new Promise(resolve => setTimeout(resolve, 1000, 'here'))
p.then(console.log)
//in one second 'here'
您可以看到,直到承诺解决之后,然后才真正发生。使用异步代码,只要解决方法被调用即可。
因此,您的代码中发生的情况如下:
Create Promise -> set event loop callback
console.log(isBound) // false, but happens first because it's called sync
Promise resolves // true
因此,在您的承诺解决方案中,实际上甚至是您能够成功对其进行检查的第一位。如果您从通话中将其退回,则可以链接到那里,并确保以后继续作用域。
let a = 0
let p = Promise.resolve(a)
.then(a =>{
a += 2;
return a;
})
.then(a => console.log(a) || a)
console.log(a) // 0
p == p.then(a =>{
a += 4;
return a;
})
.then(console.log) // false because promises aren't equal and .then/.catch return new promise chains
// 2
// 6
由于事件循环,2,6和错误的比较可能会输出不正确,但是,如果将它们都放在相同的词法范围内,那么您仍然可以访问a
或{{1 }}在您的诺言链范围之内。
侧面说明:您无需在类方法内使用箭头函数引用this
与_this
。它们将按词法作用域,因此这将绑定到该函数的局部作用域。有关更多信息,请访问You Don't know JS
答案 2 :(得分:-1)
您正在尝试在创建承诺时(而不是在解决承诺时)设置isBound
。
您可以将其存储在变量中,在其上调用authenticate()
,然后再返回诺言链,而不是直接从.then()
方法返回诺言。
authenticate(credentials) {
// create your promise and store it
let authPromise = new Promise((resolve, reject) => {
...
})
// handle the promise and set isBound before returning the chain
return authPromise.then(res => {
_this.isBound = true
return res
})
}
这可以用更少的行写,但这是为了说明在返回之前的承诺链和拦截。
ADDITIONALLY 您的最后一个console.log()
在您的诺言处理程序(.then()
)之外,因此它始终为null,因为在身份验证异步之前,该代码是同步运行的功能有时间完成。
client.authenticate(credentials)
.then(res => {
// you MUST do all your async-dependant operations inside
// promise handlers like this
console.log(client.isBound);
})