React Native:如何直接调用Promise类型仓库方法,无需then链式调用
问题:如何直接调用Repository的方法,避免嵌套then调用
我有多个包含getUser、getUsers等数据库调用的repositories,当前按如下方式导出这些仓库:
import { DatabaseBackend } from "../common/database"; import { userRepository as _userRepository, bookingRepository as _bookingRepository, pricingRepository as _pricingRepository, } from "../common/repositories"; const backend = DatabaseBackend.ReactNative; export const userRepository = _userRepository(backend); export const bookingRepository = _bookingRepository(backend); export const pricingRepository = _pricingRepository(backend);
这导致我需要编写嵌套then的调用代码:
const fetchUserData = (uid: string) => { userRepository .then((u) => { u.getUser(uid) .then((user: User) => { if(!user) { return; } setUser(user); }) .catch((err) => { logger.error("Something went wrong while fetching user information", err); }); }) .catch(err => { logger.error("Something went wrong while fetching user information", err); }); };
根据类型提示,userRepository是一个Promise:
const userRepository: Promise<{ getUser: (id: string) => Promise<User>; getNanny: (id: string) => Promise<Nanny>; getNannies: () => Promise<Nanny[]>; getParent: (id: string) => Promise<Parent>; updateUser: (user: User) => Promise<void>; }>
请问是否有办法无需通过then调用,直接将函数赋值给userRepository,让我可以直接调用userRepository.getUser()这类方法?
解决方案
1. 用async/await简化现有代码(最快实现)
不需要改动Repository的导出逻辑,只需要在调用时用async/await替代嵌套then,代码会简洁很多:
const fetchUserData = async (uid: string) => { try { const repo = await userRepository; const user = await repo.getUser(uid); if (user) { setUser(user); } } catch (err) { logger.error("Something went wrong while fetching user information", err); } };
2. 改造Repository创建逻辑,同步返回实例
如果_userRepository(backend)不需要异步初始化(比如只是同步配置后端,没有异步IO),可以修改../common/repositories里的实现,让它同步返回Repository实例,而不是Promise。
比如原异步实现:
// ../common/repositories 旧代码 export const userRepository = (backend) => { return new Promise(resolve => { // 异步初始化逻辑 resolve({ getUser: () => ... }); }); };
改成同步返回:
// 修改后的代码 export const userRepository = (backend) => { // 同步配置并返回实例 return { getUser: (id) => fetchUserFromBackend(backend, id), // 其他方法... }; };
这样导出的userRepository就不再是Promise,而是直接可用的对象,能直接调用userRepository.getUser(uid)。
3. 创建代理层包装Promise方法(适合无法修改原Repository的情况)
如果无法修改原Repository的异步初始化逻辑,可以创建一个代理对象,自动处理Promise的等待:
// 封装工具函数,把Promise包装成可直接调用方法的对象 const createRepoProxy = (repoPromise) => { return new Proxy({}, { get(target, prop) { return async (...args) => { const repo = await repoPromise; return repo[prop](...args); }; } }); }; // 导出时使用代理 export const userRepository = createRepoProxy(_userRepository(backend)); export const bookingRepository = createRepoProxy(_bookingRepository(backend));
之后就能直接调用方法,内部会自动等待Repository初始化完成:
const fetchUserData = async (uid: string) => { try { const user = await userRepository.getUser(uid); if (user) { setUser(user); } } catch (err) { logger.error("Something went wrong while fetching user information", err); } };
内容的提问来源于stack exchange,提问作者Sylent
相关产品推荐
相关产品推荐

