Как понять цепочки обещаний? - PullRequest
1 голос
/ 13 июля 2020

Я делал Java, а затем Kotlin в течение многих лет .. но по какой-то причине я просто не могу осмыслить эти JS цепочки обещаний ...

У меня есть последние 2 часов пытались понять, как мне вернуть только зашифрованную строку из этого примера кода AES или что-нибудь еще из такой цепочки.

import { NativeModules, Platform } from 'react-native'

const Encrypt = (message) => {
    const Aes = NativeModules.Aes

    const options = {
        password: "Password",
        salt: "salt",
        cost: 5000,
        length: 256
    }

    const GenerateKey = (password, salt, cost, length) => { 
        Aes.pbkdf2(
            password || options.password,
            salt || options.salt, 
            cost || options.cost, 
            length || options.length
        ) 
    }

    const DecryptData = (cipher, iv, key) => Aes.decrypt(cipher, key, iv)

    const EncryptData = (text, key) =>  {
        return Aes.randomKey(16).then(iv => {
            return Aes.encrypt(text, key, iv).then(cipher => ({
                cipher,
                iv
            }))
        })
    }

    const example = () => {
        generateKey('asd', 'salt', 2000, 256)
        .then( key => {
            console.log('Key:', key)
            encryptData(message, key)
                .then(({ cipher, iv }) => {
                    console.log('Encrypted:', cipher)
                    decryptData(cipher, iv, key)
                        .then(text => {
                            console.log('Decrypted:', text) 
                        })
                        .catch(error => {
                            console.log(error)
                        })
     
                    Aes.hmac256(cipher, key).then(hash => {
                        console.log('HMAC', hash)
                    })
                })
                .catch(error => {
                    console.log(error)
                })
        })
    }
}

export default Encrypt

Все журналы консоли срабатывают, если я сниму объявление функции в примере, поэтому код должен работать.

Вопрос 1: Как мне вернуть только шифр из цепочки?

Вопрос 2: Могу ли я как-то экспортировать только функцию EncryptData, чтобы использовать ее отдельно?

Вопрос 3: Есть ли у кого-нибудь какие-либо ресурсы, такие как учебник, который помог бы вам понять этот поток?

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

Спасибо

1 Ответ

2 голосов
/ 13 июля 2020

Итак, насколько я понимаю, ваш собственный компонент Aes имеет 5 функций: pbkdf2, decrypt, encrypt, randomKey и hmac256.

Более гибкий и читаемый способ делать то, что вы хотите, - использовать asyn c await для каждой функции "обещания".

Итак, в основном я бы сделал это:

const Encrypt = (message) => {
    const Aes = NativeModules.Aes

    const options = {
        password: "Password",
        salt: "salt",
        cost: 5000,
        length: 256
    }

    const generateKey = (password, salt, cost, length) => { 
        return Aes.pbkdf2(
            password || options.password,
            salt || options.salt, 
            cost || options.cost, 
            length || options.length
        ) 
    }

    const decryptData = (cipher, iv, key) => Aes.decrypt(cipher, key, iv)

    const encryptData = async (text, key) =>  {
        const iv = await Aes.randomKey(16);
        const cipher = await Aes.encrypt(text, key, iv);
        return { cipher, iv };
    }

    const example = async () => {
        try {
            const key = await generateKey('asd', 'salt', 2000, 256);
            console.log('Key:', key);

            const { cipher, iv } = await encryptData(message, key);
            console.log('Encrypted:', cipher);
            const text = await decryptData(cipher, iv, key);

            console.log('Decrypted:', text);

            const hash = await Aes.hmac256(cipher, key);
            console.log('HMAC', hash);
        } catch (err) {
            console.log('Error:', err);
        }
    }
}

Если вам нужна функция, возвращающая шифр, вы можете либо вернуть шифр в примере используйте асинхронный способ, или вы отправляете функцию обратного вызова.

Асинхронный способ:

const EncryptData = async (message) => {
    const Aes = NativeModules.Aes

    const options = {
        password: "Password",
        salt: "salt",
        cost: 5000,
        length: 256
    }

    const generateKey = (password, salt, cost, length) => { 
        return Aes.pbkdf2(
            password || options.password,
            salt || options.salt, 
            cost || options.cost, 
            length || options.length
        ) 
    }

    const decryptData = (cipher, iv, key) => Aes.decrypt(cipher, key, iv)

    const encryptData = async (text, key) =>  {
        const iv = await Aes.randomKey(16);
        const cipher = await Aes.encrypt(text, key, iv);
        return { cipher, iv };
    }
    
    const key = await generateKey('asd', 'salt', 2000, 256);
    console.log('Key:', key);

    const { cipher, iv } = await encryptData(message, key);
    return cipher;
}

функция обратного вызова

const EncryptData = async (message, onSuccess, onError) => {
    const Aes = NativeModules.Aes

    const options = {
        password: "Password",
        salt: "salt",
        cost: 5000,
        length: 256
    }

    const generateKey = (password, salt, cost, length) => { 
        return Aes.pbkdf2(
            password || options.password,
            salt || options.salt, 
            cost || options.cost, 
            length || options.length
        ) 
    }

    const decryptData = (cipher, iv, key) => Aes.decrypt(cipher, key, iv)

    try {
        const encryptData = async (text, key) =>  {
            const iv = await Aes.randomKey(16);
            const cipher = await Aes.encrypt(text, key, iv);
            return { cipher, iv };
        }
    
        const key = await generateKey('asd', 'salt', 2000, 256);
        console.log('Key:', key);

        const { cipher, iv } = await encryptData(message, key);
        if (typeof onSuccess === 'function') onSuccess(cipher);
    } catch (err) {
        if (typeof onError === 'function') onError(err);
    }
}

Если вы хотите больше узнать о обещаниях и asyn c await, я предлагаю эти 2 видео:

Promises in 100 Seconds

Asyn c Await

...