使用 Node.Js 和 Promises,你如何返回一个已经实现的 Promise? [复制]
Posted
技术标签:
【中文标题】使用 Node.Js 和 Promises,你如何返回一个已经实现的 Promise? [复制]【英文标题】:Using Node.Js and Promises, how do you return a fulfilled promise? [duplicate] 【发布时间】:2018-10-14 08:33:04 【问题描述】:我正在使用 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。如果你处于一个处于 Promise 内部并且想要将值返回到链中的情况,你会怎么做?
【问题讨论】:
对于猫鼬 API,return Customer.findOneAndUpdate( email , , "upsert": true, "new": true )
。除了"new": true
而不是"returnOriginal": false
之外,基本上与标准API 相同。当数据库已经这样做时,无需链接承诺。
太美了!
【参考方案1】:
这里不需要 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()
通常适用于没有实际异步操作发生的特殊情况的操作,但为了保持一致性,您仍然希望它们在这些情况下返回 Promise。
作为一个简单的例子,假设我有一堆具有uid
属性的对象,它们可能有也可能没有相应的username
属性。我想确保它们都具有username
属性,因此我编写了一个可以调用所有它们的函数,如果缺少用户名,它将从数据库中查找用户名。为了保持一致性,我希望这个函数总是返回一个承诺,即使 username
已经存在并且实际上不需要查找。另外,我可以添加一个案例,如果 uid
丢失,promise 将拒绝而不会浪费时间尝试将 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.resolve
中并将then
链接到它上面:
function foo(cb)
return Promise.resolve(cb())
.then((callbackResult) =>
// Do whatever...
);
无论cb
返回一个使用callbackResult
解析的promise 还是直接返回callbackResult
,这都将起作用。
【讨论】:
我尝试了“Promise.resolve(cb())”并收到错误。我不知道 API 是否不同,但在我的 Node.js/Express 中这似乎无效。我在传统的 JS 中见过很多这种方法。 我不希望它适用于您的代码,因为您没有使用这样的回调。这只是一个通用示例,我将其作为Promise.resolve
用途的演示。我经常发现了解某物的用途更容易理解它不的用途。 :)以上是关于使用 Node.Js 和 Promises,你如何返回一个已经实现的 Promise? [复制]的主要内容,如果未能解决你的问题,请参考以下文章
如何在Node.js中对使用promises和事件发射器的函数进行单元测试?
如何使用 node.js 和 Promises 将特定行的行添加到文件的内容
使用 Javascript(以及 Node.js)使用 async/await 和 Promises 的正确方法是啥 [重复]
Node.js:何时使用 Promises 与 Callbacks