Javascript Обещание с нуля - PullRequest
       0

Javascript Обещание с нуля

0 голосов
/ 19 февраля 2020

Я получил ошибку при написании базового c обещания с нуля и не знаю, почему this.status выдает ошибку

class Promisify {
  constructor(fn) {
    this.status = 0; // 0 = unfulfilled, 1 = resolved, 2 = rejected
    this.result = undefined;
    this.error = undefined;
    this.thenFns = [];
    this.catchFns = [];
    this.finallyFn = undefined;

    try {
      fn(this._resolve, this._reject);
    } catch (e) {
      this._reject(e);
    }
  }


  // public methods
  then(fn) {
    this.thenFns.push(fn);
    this._doThen();
    return this;
  }

  catch(fn) {
    this.catchFns.push(fn);
    this._doCatch();
    return this;
  };
  
  finally(fn) {
    this.finallyFn = fn;
    return this;
  }

  // private methods
  _doThen() {
    if (this.status === 1) {
      while(this.thenFns.length) {
        this.thenFns.shift()(this.result);
      }
    }
  }

  _doCatch() {
    if (this.status === 2) {
      if (this.catchFns.length === 0) {
        console.error('uncaught error')
      }
      while(this.catchFns.length) {
        this.catchFns.shift()(this.error);
      }
    }
  }

  _resolve(r) {
    if(this.status) 
      throw Error('cannot resolve, already handled');
    this.status = 1;
    this.result = r;
    this._doThen();
  }
  
  _reject(e) {
    if (this.status) throw Error('cannot reject, already handled');
    this.status = 2;
    this.error = e;
    this._doCatch();
  }
}

Ответы [ 3 ]

2 голосов
/ 19 февраля 2020

Если вы хотите передать свои функции кому-то еще, чтобы они вызывали с помощью

 fn(this._resolve, this._reject);

и чтобы this указывали на ваш объект обещания при их вызове, вам необходимо явно связать их:

  fn(this._resolve.bind(this), this._reject.bind(this));

class Promisify {
   constructor(fn) {
     this.status = 0; // 0 = unfulfilled, 1 = resolved, 2 = rejected
     this.result = undefined;
     this.error = undefined;
     this.thenFns = [];
     this.catchFns = [];
     this.finallyFn = undefined;
 
     try {
       fn(this._resolve.bind(this), this._reject.bind(this));
     } catch (e) {
       this._reject(e);
     }
   }
 
   // public methods
   then(fn) {
     this.thenFns.push(fn);
     this._doThen();
     return this;
   }
 
   catch(fn) {
     this.catchFns.push(fn);
     this._doCatch();
     return this;
   };
   
   finally(fn) {
     this.finallyFn = fn;
     return this;
   }
 
   // private methods
   _doThen() {
     if (this.status === 1) {
       while(this.thenFns.length) {
         this.thenFns.shift()(this.result);
       }
     }
   }
 
   _doCatch() {
     if (this.status === 2) {
       if (this.catchFns.length === 0) {
         console.error('uncaught error')
       }
       while(this.catchFns.length) {
         this.catchFns.shift()(this.error);
       }
     }
   }
 
   _resolve(r) {
     if(this.status) 
       throw Error('cannot resolve, already handled');
     this.status = 1;
     this.result = r;
     this._doThen();
   }
   
   _reject(e) {
     if (this.status) throw Error('cannot reject, already handled');
     this.status = 2;
     this.error = e;
     this._doCatch();
   }
 }
 

 const demo = new Promisify((resolve, reject) => {
   setTimeout(function() {
     resolve('Howdy!')
   }, 1000);
 });
 
 demo
.then(val => console.log("Demo Value in Then!!", val))
.catch(console.error) //Should throw an error.
.then(val => console.log("Second then!"))
.catch((err) => {
    throw new Error('error', err);
})
.finally(val => console.log("Executed Finally"))
 
0 голосов
/ 19 февраля 2020

Простое обещание построить с нуля



class Promisify 
{
  constructor(fn)
  {
    this._function1 = fn; 
  }

  finally()
  {
    console.log('finally executed');
  }

  catch(error)
  {
    console.log('catch executed');
    return this;
  }

  then(resolve, reject)
  {
    try
    {
      this._function1(resolve, reject);  
      return this;
    }
    catch(err)
    {
       this.catch(err);
       return this;
    }

    this.finally();

  }

}

let promise = new Promisify(function(resolve, reject)
{
    console.log('promise executed');

    resolve('resolved');
})

promise
.then(function(input)
{
   console.log(input);
})
.then(function(input)
{
   console.log('second then');
})
0 голосов
/ 19 февраля 2020

Эта проблема возникает из-за того, что scoping.y Вы вызываете resol и reject из нового вызова функции Promise, который имеет свою собственную область.

В этом случае вам необходимо привязать объект класса Promisify для разрешения и отклонения метода это сработает, в основном эта проблема возникает из-за 'this'

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...