使用Node.Js和Promises,你如何回报履行的承诺?

时间:2018-05-03 23:17:10

标签: node.js mongodb mongoose promise

我使用的是Mongoose,我正处于从数据库中查找客户的情况。如果客户存在,我将返回customerId。但是,如果客户不存在,我想创建它们然后返回客户ID。在任何一种情况下,我都希望承诺以customerID结束。无论如何,虽然我在文档中看到可以使用“Promise.resolve”立即包装返回值,但我收到错误。当尝试通过包装返回值来使同步任务与Node更一致时,此功能显然非常有用。无论如何,有什么更好的方法来处理这个或回报承诺?在一天结束时,我希望代码返回客户对象或陷入捕获/错误。

TypeError: Promise.resolve is not a constructor

下面是代码(我编辑了一些安全事项,但我认为我没有做任何严重的修改)。

Customer.findOne({email: email}).then((customer) => {
    if (customer) {
        return  Promise.resolve(customer);
    }
    else {
        return new Customer({email: email}).save();
    }    
}).then( function(customer) {...

这真的是关于Promises,而不是Mongoose或MongoDb。如果您处于承诺范围内且希望将价值返回给链条的情况下,您会怎么做?

1 个答案:

答案 0 :(得分:0)

你不需要Promise.resolve()。如果then处理程序返回非承诺,then调用返回的承诺将使用该值解析。换句话说,它已经被包裹了,所以再次包装它是多余的。

在一个不相关的说明中,else也是多余的,因为return语句退出当前正在执行的函数:

Customer.findOne({email: email}).then((customer) => {
    if (customer) {
        return customer;
    }
    return new Customer({email: email}).save();    
}).then( function(customer) {...

Promise.resolve()Promise.reject()通常用于具有特殊情况但不会发生实际异步操作的操作,但您仍然希望它们在这些情况下返回承诺以保持一致性&#39为了这个缘故。

作为一个简单的例子,假设我有一堆具有uid属性的对象,可能有也可能没有相应的username属性。我想确保它们都具有username属性,因此我编写了一个可以调用所有这些函数的函数,如果缺少该函数,它将从数据库中查找用户名。为了保持一致性,我希望此函数始终返回一个promise,即使username已经存在且实际上不需要查找。另外,我可以添加一个案例,在uid丢失的情况下,承诺将拒绝,而不会浪费时间尝试查找undefined作为uid。

看起来像这样:

function ensureUsername(user) {
    if ('username' in user) return Promise.resolve(user);
    return lookUpUsernameByUid(user.uid)
        .then((username) => {
            user.username = username;
            return user;
        });
}

Promise.resolve()在处理可能或可能不是承诺的值时也非常有用。这是因为它只是返回值,如果它已经是一个承诺。

假设你想编写一个调用某些回调函数的函数foo。回调函数可能是也可能不是异步的 - 即它可以返回一个promise,但不是必需的。你是如何做到这一点的?

很简单。只需将回调结果放在Promise.resolve中并将then链接到其上:

function foo(cb) {
    return Promise.resolve(cb())
        .then((callbackResult) => {
            // Do whatever...
        });
}

这将有效,cb是否会返回以callbackResult结算的承诺,或者只是直接返回callbackResult