Skip to content

Instantly share code, notes, and snippets.

@EndyKaufman
Created November 25, 2019 20:27
Show Gist options
  • Save EndyKaufman/e5004e3b6584b46b0701cea9e649d978 to your computer and use it in GitHub Desktop.
Save EndyKaufman/e5004e3b6584b46b0701cea9e649d978 to your computer and use it in GitHub Desktop.
callback-to-observable.ts
import { Inject, Injectable } from '@nestjs/common';
import { from, Observable } from 'rxjs';
/**
* Костыль который превращает функции сервиса с калбак аргументом в обзервабл,
* для поддержки типизации в тестах
*
* @param service сервис созданный через загрузку прото файла (GRPC.loadPackageDefinition)
*/
// tslint:disable-next-line: typedef
export function callbackToObservable<T = Observable<any>>(service: T, showErrors = true) {
return new Proxy(
{},
{
// tslint:disable-next-line: typedef
get(target, name) {
// tslint:disable-next-line: typedef
return function() {
if (arguments.length === 0) {
return from(
new Promise((resolve, reject) => {
try {
service[name](callback(name, reject, resolve, showErrors));
} catch (error) {
callback(name, reject, resolve, showErrors)(error, null);
}
})
);
}
if (arguments.length === 1) {
return from(
new Promise((resolve, reject) => {
try {
service[name](arguments[0], callback(name, reject, resolve, showErrors));
} catch (error) {
callback(name, reject, resolve, showErrors)(error, null);
}
})
);
}
if (arguments.length === 2) {
return from(
new Promise((resolve, reject) => {
try {
service[name](arguments[0], arguments[1], callback(name, reject, resolve, showErrors));
} catch (error) {
callback(name, reject, resolve, showErrors)(error, null);
}
})
);
}
if (arguments.length === 3) {
return from(
new Promise((resolve, reject) => {
try {
service[name](arguments[0], arguments[1], arguments[2], callback(name, reject, resolve, showErrors));
} catch (error) {
callback(name, reject, resolve, showErrors)(error, null);
}
})
);
}
if (arguments.length === 4) {
return from(
new Promise((resolve, reject) => {
try {
service[name](arguments[0], arguments[1], arguments[2], arguments[3], callback(name, reject, resolve, showErrors));
} catch (error) {
callback(name, reject, resolve, showErrors)(error, null);
}
})
);
}
// эта штука не работает, пришлось вызывать явно - выше ифы
return from(
new Promise((resolve, reject) => {
try {
service[name].apply(null, [...Array.from(arguments), callback(name, reject, resolve, showErrors)]);
} catch (error) {
callback(name, reject, resolve, showErrors)(error, null);
}
})
);
};
}
}
) as T;
function callback(name: string | number | symbol, reject: (reason?: any) => void, resolve: (value?: unknown) => void, showCallbackErrors: boolean): any {
return (err, res) => {
setTimeout(() => {
if (err) {
if (showCallbackErrors) {
console.error(`Error in run method "${String(name)}"`);
}
reject(err);
} else {
resolve(res);
}
}, 1000);
};
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment