如何更自然地从JS/Node函数返回已决议Promise(无需Promise.resolve)
优化Mongoose异步方法的Promise返回方式
问题描述
我正在编写一个Mongoose工具方法,希望在异步方法执行完成后返回对应结果,以下是简化示例:
const testConnect = () => { let msg; mongoose.connect(mongoServer.getUri()) .then(() => { msg = "Connection success!"; }) .catch((err) => { msg = "Connection failure! Error: " + err; }); return Promise.resolve(msg); };
测试代码调用方式如下:
beforeAll(() => { iMDT.testConnect() .then((result) => { console.log(result); }) .catch((err) => { console.log(err); }); });
当前用Promise.resolve返回结果的方式比较繁琐,想找更简洁自然的方式返回已决议Promise,不用手动调用Promise原型方法。
优化方案
得先提一句:你的原代码有异步时序问题——return Promise.resolve(msg)会在mongoose.connect的异步操作完成前执行,此时msg还是undefined,根本拿不到正确结果。下面是两种既正确又简洁的实现方式:
方式1:直接返回Promise链
不用额外声明msg变量,直接在then和catch里返回对应消息,方法整体返回mongoose.connect生成的Promise就行:
const testConnect = () => { return mongoose.connect(mongoServer.getUri()) .then(() => "Connection success!") .catch((err) => `Connection failure! Error: ${err}`); };
这样方法本身就会返回一个已决议的Promise:连接成功时resolve成功消息,失败时resolve失败消息。如果希望失败时让调用方进入catch分支,把catch里的返回改成throw new Error(Connection failure! Error: ${err})即可。
方式2:用async/await语法(更直观)
async/await能把异步代码写成同步风格,可读性更强,而且带async关键字的方法会自动返回Promise,完全不用手动创建:
const testConnect = async () => { try { await mongoose.connect(mongoServer.getUri()); return "Connection success!"; } catch (err) { return `Connection failure! Error: ${err}`; // 若需让调用方捕获错误,这里改成 throw new Error(`Connection failure! Error: ${err}`) } };
这里return的值会自动成为Promise的resolve结果,throw的错误则会成为reject结果,全程不用碰Promise原型方法。
调用代码也能简化
你的测试代码同样可以用async/await简化:
beforeAll(async () => { try { const result = await iMDT.testConnect(); console.log(result); } catch (err) { console.log(err); } });
内容的提问来源于stack exchange,提问作者rainydaymatt
相关产品推荐
相关产品推荐

