Ex 10

문제

/*

Intro:

    We have asynchronous functions now, advanced technology.
    This makes us a tech startup officially now.
    But one of the consultants spoiled our dreams about
    inevitable future IT leadership.
    He said that callback-based asynchronicity is not
    popular anymore and everyone should use Promises.
    He promised that if we switch to Promises, this would
    bring promising results.

Exercise:

    We don't want to reimplement all the data-requesting
    functions. Let's decorate the old callback-based
    functions with the new Promise-compatible result.
    The final function should return a Promise which
    would resolve with the final data directly
    (i.e. users or admins) or would reject with an error
    (or type Error).

    The function should be named promisify.

Higher difficulty bonus exercise:

    Create a function promisifyAll which accepts an object
    with functions and returns a new object where each of
    the function is promisified.

    Rewrite api creation accordingly:

        const api = promisifyAll(oldApi);

*/

interface User {
    type: 'user';
    name: string;
    age: number;
    occupation: string;
}

interface Admin {
    type: 'admin';
    name: string;
    age: number;
    role: string;
}

type Person = User | Admin;

const admins: Admin[] = [
    { type: 'admin', name: 'Jane Doe', age: 32, role: 'Administrator' },
    { type: 'admin', name: 'Bruce Willis', age: 64, role: 'World saver' }
];

const users: User[] = [
    { type: 'user', name: 'Max Mustermann', age: 25, occupation: 'Chimney sweep' },
    { type: 'user', name: 'Kate MΓΌller', age: 23, occupation: 'Astronaut' }
];

export type ApiResponse<T> = (
    {
        status: 'success';
        data: T;
    } |
    {
        status: 'error';
        error: string;
    }
);

export function promisify(arg: unknown): unknown {
    return null;
}

const oldApi = {
    requestAdmins(callback: (response: ApiResponse<Admin[]>) => void) {
        callback({
            status: 'success',
            data: admins
        });
    },
    requestUsers(callback: (response: ApiResponse<User[]>) => void) {
        callback({
            status: 'success',
            data: users
        });
    },
    requestCurrentServerTime(callback: (response: ApiResponse<number>) => void) {
        callback({
            status: 'success',
            data: Date.now()
        });
    },
    requestCoffeeMachineQueueLength(callback: (response: ApiResponse<number>) => void) {
        callback({
            status: 'error',
            error: 'Numeric value has exceeded Number.MAX_SAFE_INTEGER.'
        });
    }
};

export const api = {
    requestAdmins: promisify(oldApi.requestAdmins),
    requestUsers: promisify(oldApi.requestUsers),
    requestCurrentServerTime: promisify(oldApi.requestCurrentServerTime),
    requestCoffeeMachineQueueLength: promisify(oldApi.requestCoffeeMachineQueueLength)
};

function logPerson(person: Person) {
    console.log(
        ` - ${person.name}, ${person.age}, ${person.type === 'admin' ? person.role : person.occupation}`
    );
}

async function startTheApp() {
    console.log('Admins:');
    (await api.requestAdmins()).forEach(logPerson);
    console.log();

    console.log('Users:');
    (await api.requestUsers()).forEach(logPerson);
    console.log();

    console.log('Server time:');
    console.log(`   ${new Date(await api.requestCurrentServerTime()).toLocaleString()}`);
    console.log();

    console.log('Coffee machine queue length:');
    console.log(`   ${await api.requestCoffeeMachineQueueLength()}`);
}

startTheApp().then(
    () => {
        console.log('Success!');
    },
    (e: Error) => {
        console.log(`Error: "${e.message}", but it's fine, sometimes errors are inevitable.`);
    }
);

// In case you are stuck:
// https://www.typescriptlang.org/docs/handbook/2/generics.html

풀이

api 객체λ₯Ό 보면 4개의 속성듀이 promisify의 결과값을 μ˜λ―Έν•˜κ³  μžˆλ‹€. λ”°λΌμ„œ oldApiλ₯Ό ν•œ κ³³μ—μ„œ 관리할 ν•¨μˆ˜ promisify의 νƒ€μž…μ„ μ§€μ •ν•΄μ•Όν•œλ‹€.

λ¨Όμ €, λ§€κ°œλ³€μˆ˜μ˜ κ°’κ³Ό λ¦¬ν„΄κ°’μ˜ νƒ€μž…μ΄ 각각 λ‹€λ₯΄κΈ° λ•Œλ¬Έμ— μ œλ„€λ¦­μ„ μ‚¬μš©ν•΄ νƒ€μž…μ„ μ§€μ •ν•΄μ€€λ‹€. λ¦¬ν„΄κ°’μ˜ 경우, λ¬Έμ œμ— 적힌 λŒ€λ‘œ Promise λ₯Ό 좜λ ₯ν•˜κ²Œλ” μ§€μ •ν•œλ‹€.

그리고 api μ—μ„œ promisify ν•¨μˆ˜μ— μ œλ„€λ¦­ νƒ€μž…μ„ μΆ”κ°€ν•΄μ£Όλ©΄ λ¬Έμ œλŠ” ν•΄κ²°λœλ‹€.

+

λ³΄λ„ˆμŠ€ 문제인 promisifyAll κ΅¬ν˜„μ€ λ‚˜μ€‘μ— λ‹€μ‹œ μ‹œλ„ν•΄λ³΄μž

Last updated