свойство класса доступа, установленное внутри обещания - PullRequest
0 голосов
/ 29 июня 2018

Исходя из обширного фона в 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)

Я пытаюсь получить доступ к свойству isBound вне возврата обещания, где оно установлено в true в методе аутентификации при успешном завершении.

Однако, как вы можете видеть, возможно, существует состояние гонки?

Есть ли способ справиться с этим ...

Спасибо

Ответы [ 3 ]

0 голосов
/ 29 июня 2018

Это не состояние гонки. Работает нормально, как и ожидалось. В вашем коде есть два console.logs. Первый в обещании, а другой вне обещания.

Ваш вызов переходит в асинхронный режим, и последние console.log выполняются последовательно в качестве следующей команды по порядку, что в то время значением переменной было null. Ваша переменная разрешается позже с правильным значением.

Если вам нужно выполнить дальнейшие действия, вы должны сделать это в .then() части вашего Client метода, который будет выполняться только после разрешения вашего Promise.

Например

Client().then() {//all of your post response related logic should be here}
0 голосов
/ 29 июня 2018

Значит, вы что-то неправильно поняли об обещаниях. Они предназначены для использования в асинхронном коде, например:

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 или this в пределах границы вашей цепочки обещаний.


Примечание: вам не нужно ссылаться на _this против this с функцией стрелки внутри методов класса. Они будут иметь лексическую область видимости, и, таким образом, это будет связано с локальной областью действия этой функции. Более подробную информацию можно найти на Вы не знаете JS

0 голосов
/ 29 июня 2018

Вы пытаетесь установить 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
  })
}

Это может быть написано с меньшим количеством строк, но это предназначено для иллюстрации цепочки обещаний и перехвата перед возвратом.

ДОПОЛНИТЕЛЬНО Ваш окончательный console.log() находится за пределами вашего обработчика обещаний (.then()), поэтому он всегда будет нулевым, поскольку этот код запускается синхронно, до того как асинхронная функция аутентификации успеет завершиться .

client.authenticate(credentials)
  .then(res => {
    // you MUST do all your async-dependant operations inside
    // promise handlers like this
    console.log(client.isBound);
  })
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...