返回一个promise而无需在nodejs中等待函数中的依赖promise

时间:2017-12-06 19:51:59

标签: node.js promise es6-promise

我正在使用节点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);
}

问题是函数在返回我不想要的控件之前等待地址。 (或者它不会产生任何差异,因为函数是异步的。性能是我的一个重要标准)

如何处理这种承诺依赖性,你想要返回父对象的承诺,但是你的父对象依赖于子对象的承诺。

谢谢。

5 个答案:

答案 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