我正在使用节点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函数以异步方式执行,即尽快返回一个promise而不等待创建地址对象。
这个问题的目的不是要完成任务,而是要了解在异步编程中解决此类问题的最佳方法是什么。
我能想到的几种方式: 1:创建一个新的promise对象,并在createUser函数中输入后立即返回。创建用户对象时解析它。 2:使createUser成为异步函数,然后返回用户Promise。面对这个方法的问题:
async function createUser()
{
address = await createAddress();
return User.create(name: 'foo', address: userAddress);
}
问题是函数在返回我不想要的控件之前等待地址。 (或者它不会产生任何差异,因为函数是异步的。性能是我的一个重要标准)
如何处理这种承诺依赖性,你想要返回父对象的承诺,但是你的父对象依赖于子对象的承诺。
谢谢。
答案 0 :(得分:2)
你可以按原样编写你的函数,然后它取决于它的调用方式。您无法使用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
答案 1 :(得分:1)
使createUser成为异步函数,然后返回用户Promise。问题是函数在返回我不想要的控件之前等待地址。
不,它没有。 async function
会立即向其调用者返回一个承诺。它仅在执行其正文中的代码时等待(并在return
时解析承诺)。你的代码有效,这正是你应该做的。
答案 2 :(得分:0)
如果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
这将要求您在执行其他代码之前等待承诺得到解决。
答案 3 :(得分:0)
如果您想要回复承诺,那么您基本上希望以预期的方式使用承诺:
createUser() {
return createAddress()
.then((address) =>
User.create({ name: 'foo', address: address })
);
}
现在createUser
方法正在返回一个promise,它将在未来的某个时候解决。您的代码可以继续工作,可以为该承诺添加更多.then(...)
或.catch(...)
回调等。
答案 4 :(得分:0)
这是另一种方法,假设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