从JavaScript/Node函数中解析并返回已解析的promise,有比使用Promise更自然的方法吗?

wdebmtf2  于 2023-06-05  发布在  Node.js
关注(0)|答案(3)|浏览(168)

例如,我正在编写一个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返回--而不使用原型Promise?我觉得很笨拙。

omjgkv6w

omjgkv6w1#

你尝试做的事情不会起作用,因为你的异步操作是非阻塞的,所以你会在msg中有一个值之前就做return Promise.resolve(msg);。当您在.then().catch()处理程序中分配更高范围的变量,然后试图在顶部范围使用这些变量时,这几乎总是一个警告信号。由于计时问题(试图在设置变量值之前使用该变量),这将不起作用。
相反,您可以直接返回promise。一般的建议是使用你已经拥有的promise,不要创建不必要的新promise。返回您已经拥有的一个,如下所示:

const testConnect = () => {
    return mongoose.connect(mongoServer.getUri()).then(() => {
        // set the final resolved value
        return "Connection success!";
    }).catch((err) => {
        // set the final rejected reason object
        throw new Error("Connection failure! Error:"  + err.message, { cause: err });
    });
};

请注意,失败代码路径如何返回一个被拒绝的promise,其中包含一条人类可读的消息,还包含原始错误对象cause。这是使用promise的常用方式,而不是通过返回不同的resolved值来隐藏拒绝。这允许调用方更容易地知道操作是成功还是失败,而不必与特定的解析值进行比较。
而且,这也是您的beforeAll()代码块所期望的。如果操作失败,它会期待一个rejected promise,这不是您的第一个代码块所做的。

pkwftd7m

pkwftd7m2#

下面的示例演示了以清晰简洁的方式呈现的优化代码。如果有更好的答案,请分享一些其他的方法,我也想获得一些知识。谢谢你。

const testConnect = () => {
  return mongoose.connect(mongoServer.getUri())
    .then(() => "Connection success!")
    .catch((err) => "Connection failure! Error: " + err);
};
ua4mk5z4

ua4mk5z43#

我是async/await的粉丝。允许透明的可读性。

const testConnect = async () => {
    try {
        await mongoose.connect(mongoServer.getUri());
        return "Connection success!";
    } catch (err) {
        throw new Error("Connection failure! Error: " + err);
    }
};

beforeAll(async () => {
    try {
        const result = await iMDT.testConnect();
        console.log(result);
    } catch (err) {
        console.log(err);
    }
});

相关问题