2015-02-20 2 views
0

Я создал небольшой класс, который обертывает общую подпись функции обратного вызова и возвращает обещание.Это, похоже, не возвращает правильный объект (TypScript)

однако тогда он называет рукоятку menthod _resolve не определен.

/// <reference path="typings/es6-promise/es6-promise.d.ts" /> 
import rsvp = require('es6-promise'); 
var Promise = rsvp.Promise; 

/** * wrapper a callback style call into a promise */ class 
Promiseify<T> { 
    private _promise : Promise<T>; 
    private _resolve : (result?: T) => void; 
    private _reject : (error: any) => void; 

    /** 
    * create wrapper, example: new Promiseify(call).promise 
    * @param call example (handle) => yourDb.update(document, handle) 
    */ 
    constructor(call:(handle:(error: any, result: T) => void) => void){ 

     this._promise = new Promise<T>((resolve, reject) =>{ 
      this._resolve = resolve; 
      this._reject = reject; 
      call(this.handle); 
     }); 

    } 

    handle(error: any, result: T) { 
     if(error != null) this._reject(error); 
     else this._resolve(result); 
    } 

    /** 
    * get the es6 promise which can then be passed to external callers 
    * @returns {Promise<T>} the es6 promise which this class creates. 
    */ 
    get promise() : Promise<T>{ 
     return this._promise; 
    } 
} 

//the test rig 
new Promiseify<string>((handle)=> { 
    handle(null, 'hello world'); 
}).promise.then((greeting: string)=> { 
     console.log(greeting); 
    }); 

я-то отсутствует, кстати, что JS под крышками выглядит слишком хорошо

также, если это помогает я бегу это на Node.js, внутри WebStorm 9,03

ответ

1

Вы передаете this.handle в call(), поэтому, когда call() называет это, this будет null, и поэтому ваш подход не работает.

Я не уверен, что будет наиболее идиоматических в машинописном, но вы можете сделать:

call(this.handle.bind(this)); 

или

call((error, result) => this.handle(error, result)); 

В качестве альтернативы, вы можете избавиться от метода handle полностью, и сделайте следующее:

this._promise = new Promise<T>((resolve, reject) => { 
    call(function (error, result) { 
     if (error) { reject(error); } 
     resolve(result); 
    }); 
}); 

но тогда это просто оставляет вопрос о том, почему лет и нужно класс вообще, когда вы могли бы вместо того, чтобы использовать функцию 8-линия, которая делает то же самое:

function promisify<T>(call:(handle:(error: any, result :T) => void) => void) { 
    return new Promise<T>((resolve, reject) => { 
     call(function (error, result) { 
      if (error) { reject(error); } 
      resolve(result); 
     }); 
    }); 
} 
+0

использовал последний, который работает. Позор этой маленькой обертки необходим. – dbones

+0

@ dbones Это необходимо, только если вы сохранили первоначальный дизайн. См. Мои правки. – JLRishe

1

У вас есть два варианта здесь:

Первый объявить метод ручки, как это свойство так:

handle = (error: any, result: T) => { 
    if(error != null) this._reject(error); 
    else this._resolve(result); 
} 

Или изменить способ вызова, так она называет его экземпляра, как показано ниже:

var that = this; 
call(function(e, r) { that.handle(e, r); }); 
Смежные вопросы