react-native - 如何理解 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 语法似乎每隔一天就会改变一次,而且这些教程似乎都不是关于这种链的。
谢谢
解决方案
所以据我了解,你的原生组件 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 的知识,我推荐这两个视频:
推荐阅读
- python-3.x - ImportError:没有系统模块'pywintypes'(pywintypes39.dll)
- java - 测试时如何从 MockWebServer 中提取参数?
- sql-server - 无法使用 SQL Server 上的链接服务器插入具有 xml 列的表
- javascript - 如何单击按钮并显示表格中的列?
- swift - 致命错误:在展开可选值 if 语句时意外发现 nil
- javascript - 从其他来源复制的 HTML 代码粘贴到主 HTML 文件的哪里?
- javascript - 获取 ElemenUi 组件 VueJs 的 id
- php - 遇到未捕获的错误:在 null 上调用成员函数 isSMTP()
- python - 在 gensim word2vec 中使用 PathLineSentences 嵌入多词 ngram 短语
- oracle - 通过删除每列之间的额外空格来格式化表格输出