首页 > 解决方案 > 如何理解 Promise 链?

问题描述

我已经做了 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:有没有人有任何资源,比如让你理解这个流程的教程?

我已经用谷歌搜索并阅读了几个教程,但 JS 语法似乎每隔一天就会改变一次,而且这些教程似乎都不是关于这种链的。

谢谢

标签: react-nativepromise

解决方案


所以据我了解,你的原生组件 Aes 有 5 个功能:pbkdf2、解密、加密、randomKey 和 hmac256。

一种更灵活、更易读的方法是在每个“承诺”函数上使用 async 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);
    }
}

如果你想了解更多关于 Promise 和 async await 的知识,我推荐这两个视频:

100 秒内的承诺

异步等待


推荐阅读