多Promise场景下应在何处执行resolve操作?
嘿,刚接触Promise不用慌~其实你用util.promisify转换后的这些Redis方法(比如getAsync、hmsetAsync),本身已经是返回Promise的函数了,promisify内部已经帮你封装好了resolve和reject的逻辑——当Redis命令执行成功时,它会自动resolve结果;执行出错时(比如连接问题、命令语法错误),会自动reject错误。你根本不需要自己手动写resolve啦!
下面结合你的使用场景,给你拆解不同情况的用法:
1. 单个Promise的基础使用
不管是调用getAsync还是incrAsync,直接用.then()接收resolve后的结果,或者用更直观的async/await语法:
// 用.then()链式调用的方式 getAsync('user:100:name') .then(username => { console.log('拿到用户名:', username); // 这里就是获取到resolve结果后的逻辑区 }) .catch(err => { console.error('获取失败:', err); }); // 更推荐的async/await写法(必须在async函数内使用) async function fetchUsername() { try { const username = await getAsync('user:100:name'); console.log('拿到用户名:', username); // await会自动等待Promise resolve,直接拿到结果 } catch (err) { console.error('获取失败:', err); } } fetchUsername();
2. 多个Promise并行执行
如果要同时执行多个无依赖的Redis操作(比如同时获取用户名称、角色、分数),用Promise.all()来批量处理——它会等待所有Promise都resolve后,按顺序返回结果数组:
async function batchFetchUserInfo() { try { // 并行发起多个Promise请求 const [username, userRoles, userScore] = await Promise.all([ getAsync('user:100:name'), smembersAsync('user:100:roles'), getAsync('user:100:score') ]); console.log('批量获取的用户信息:', { username, userRoles, userScore }); } catch (err) { // 只要有一个Promise reject,就会直接进入这里 console.error('批量操作失败:', err); } } batchFetchUserInfo();
3. 多个Promise串行执行
如果Redis操作有依赖关系(比如先自增用户ID,再用新ID创建用户哈希),就用await依次执行,每个await都会等待前一个Promiseresolve后再执行下一个:
async function createNewUser() { try { // 先执行incrAsync,拿到自增后的用户ID(这里等待Promise resolve) const newUserId = await incrAsync('next_user_id'); // 再用新ID执行hmsetAsync await hmsetAsync(`user:${newUserId}`, { name: 'Alice', age: 25, email: 'alice@example.com' }); console.log('新用户创建成功,ID:', newUserId); } catch (err) { console.error('创建用户失败:', err); } } createNewUser();
什么时候需要自己手动写resolve?
只有当你自定义封装Promise逻辑时,才需要手动调用resolve/reject。比如封装一个带重试机制的Redis获取方法:
function getWithRetry(key, retryTimes = 2) { // 手动创建Promise实例时,才需要自己写resolve/reject return new Promise(async (resolve, reject) => { try { const result = await getAsync(key); resolve(result); // 手动resolve获取到的结果 } catch (err) { if (retryTimes > 0) { console.log('获取失败,重试中...'); const retryResult = await getWithRetry(key, retryTimes - 1); resolve(retryResult); } else { reject(err); // 重试耗尽,手动reject错误 } } }); } // 使用这个自定义Promise getWithRetry('user:100:name') .then(res => console.log('最终结果:', res)) .catch(err => console.error('最终失败:', err));
总结一下:你现在用promisify转换的Redis方法都是现成的Promise函数,完全不用自己写resolve,直接用.then()或await接收结果,出错用.catch()或try/catch处理就好啦~
内容的提问来源于stack exchange,提问作者Someone Special

