返回一个promise而不等待nodejs中函数中的依赖promise
Posted
技术标签:
【中文标题】返回一个promise而不等待nodejs中函数中的依赖promise【英文标题】:Return a promise without waiting for a dependant promise in function in nodejs 【发布时间】:2018-05-20 19:30:48 【问题描述】:我正在使用节点 8.x。因此,我可以使用所有最新功能,例如 async/await 等。
场景类似于以下 (语法不正确,仅供说明):
createUser()
let userAddress = createAddress(); // Aync, returns a promise
User.create(name: 'foo', address: userAddress); // User creation is dependant on address. Also, User.create returns a promise.
基本上,用户对象的创建依赖于地址对象的创建。我希望 createUser 函数异步执行,即尽快返回一个承诺,而无需等待创建地址对象。
这个问题的目的不是完成任务,而是了解在异步编程中解决此类问题的最佳方法是什么。
我能想到的几种方法: 1:创建一个新的promise对象并在createUser函数中输入时立即返回。在创建用户对象时解决它。 2:将 createUser 设为异步函数,然后返回 user Promise。此方法面临的问题:
async function createUser()
address = await createAddress();
return User.create(name: 'foo', address: userAddress);
问题是函数在返回我不想要的控件之前等待地址。 (或者它不会产生任何差异,因为函数是异步的。在我的情况下,性能是一个重要标准)
当你想要返回父对象的承诺但你的父对象依赖于子对象的承诺时,如何处理这种承诺依赖。
谢谢。
【问题讨论】:
我对你的问题有点困惑......你想在createAddress
完成之前返回User.create
(承诺),但User.create
取决于createAddress
。
是的。我不希望函数等待地址。每当创建地址时,都应该创建用户,因此应该解决承诺。
【参考方案1】:
您可以按原样编写函数,然后取决于它的调用方式。您不能使用await
,因为它会在当前范围内阻塞。不过,您可以使用 .then
引入新范围:
async function createUser()
address = await createAddress();
return User.create( name: 'foo', address );
...
createUser().then(() => /* handle user creation */ );
// code here will not wait for `createUser` to finish
【讨论】:
【参考方案2】:将 createUser 设为异步函数,然后返回 user Promise。问题是函数在返回我不想要的控件之前等待地址。
不,它没有。 async function
确实会立即向其调用者返回一个承诺。它仅在执行其主体中的代码时等待(并在您return
时解析承诺)。您的代码有效,这正是您应该做的。
【讨论】:
谢谢。但是,如果我调试或打印到控制台,我发现它肯定不会等待地址被创建(你是对的)但是 - 控件进入 createUser - 然后它也进入 createAddress() 并返回一个承诺 -然后控件返回到调用 createUser 函数的位置。所以异步函数不会立即返回一个承诺。还是我还缺少什么? @AakashMalhotra 啊,是的,直到第一个await
(即 createAddress
调用和承诺创建)之前的所有事情都是同步发生的。只有这样 createUser
才会将其承诺返回给调用者 - 但它仍然是立即,不等待任何承诺兑现。【参考方案3】:
如果createAddress
是一个返回地址的承诺,比如说address
,你可以这样做:
createAddress().then(function(address)
User.create(name: 'foo', address: address).then(function()
// User and address has been created
)
)
// Do something here that runs even though createAddress has not yet been resolved
这将要求您在执行一些其他代码之前等待承诺得到解决。
【讨论】:
一个then()
在另一个then()
中...这是正确的吗?
@robe007 是的
为什么不呢?它基本上只是回调之上的一个相当抽象的概念。
@AakashMalhotra 我说是因为 - 对我来说 - 这被称为 嵌套承诺,我认为有一个 then()
: function createUser() return createAddress().then(function(address) return User.create(name: 'foo', address: address) // the return is to handle latter the user creation , function() throw 'Promise Rejected'; );
就足够了
@feupeu 是的,我知道,但我说的是patterns, best practices, avoid anti-patterns
;并且 chaining promises 有他们的owns【参考方案4】:
如果你想返回一个 Promise,那么你基本上是在寻找使用 Promise 的方式:
createUser()
return createAddress()
.then((address) =>
User.create( name: 'foo', address: address )
);
现在createUser
方法正在返回一个承诺,该承诺将在未来的某个时候得到解决。您的代码可以继续工作,可以向该承诺添加更多 .then(...)
或 .catch(...)
回调,等等。
【讨论】:
createAddress 函数返回的promise 是否在createUser 函数本身中得到解析,createUser() 返回的promise 是User.create 实际返回的promise 吗? 'User.create'函数前不应该有'return'关键字吗? 只要createAddress
解决了这个promise,它就会得到解决——我没有那个函数的细节,所以我不知道它什么时候得到解决。至于您的第二条评论,那就是 ES6“胖箭头”语法 - 请参阅 this link。【参考方案5】:
这是另一种方法,假设 createAddress
返回一个承诺(当然)
function createUser()
return createAddress().then(function(address)
// the return is to handle latter the user creation
return User.create(name: 'foo', address: address)
, function()
throw 'Promise Rejected';
);
createUser().then(function(result)
console.log("result => " + result);
// Do something here with the 'user creation' if you want
).catch(function(error)
console.log("error => " + error);
);
// Do some stuff, while the code above is executed
【讨论】:
这不正是@Kryten 已经发布的内容吗? (加上多余的throw
)
这是我的答案!以上是关于返回一个promise而不等待nodejs中函数中的依赖promise的主要内容,如果未能解决你的问题,请参考以下文章