如何从另一个函数内的Promise返回值? [英] How to return value from a promise that's inside another function?

查看:86
本文介绍了如何从另一个函数内的Promise返回值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道有关异步编程和Promises的问题很多,但是我确实需要一个带有此特定代码的示例,以弄清楚我应该如何返回在另一个函数中返回的Promise.

I know that a lot of questions have been asked about async programming and Promises, but I really need an example with this specific code to figure out how I should go about returning promises that's being returned in another function.

我有两个职能.GET'ing到路由时调用第一个.此路线应创建一个付款链接,并将预订保存到数据库中.

I have two functions. The first one is called upon GET'ing to a route. This route should create a payment link and save a booking to a database.

exports.create_booking = function(req, res) {

      req.body.payment = exports.create_booking_payment(req.body.total_amount);

      console.log(req.body.payment); // This returns ' Promise { <pending> } '

      var new_booking = new Booking(req.body);
      new_booking.save(function(err, booking) {
        if (err)
          res.send(err);
        res.json(booking);
      });

};

但是,创建付款链接是通过异步方法进行的.我的第一个问题是我只能在方法回调函数中访问付款.

However creating the payment link happens with an asynchronous method. My first problem was that I could only access the payment inside the methods callback function.

现在,我将方法包装在另一个(异步)方法中,在其中创建并解决了Promise.该方法将通过await语句返回到我的第一个方法,但是返回的所有内容都是:'Promise {}'.

Now I have wrapped the method inside another (async) method in which a Promise is created and resolved. This method is being returned to my first method with an await statement, but all this returns is: ' Promise { } '.

我知道发生这种情况是因为在解决诺言之前就已经返回了该方法.但是我不明白为什么会这样.我的假设是,"await"语句可确保在异步功能完成之前等待返回方法.

I know that this happens because the method is being returned before the promise is resolved. But I don't understand why this is. My assumption is that the 'await' statement makes sure to wait returning the method before the async function is completed.

exports.create_booking_payment = async function() {

function asyncPayment() {
  return new Promise (function(resolve, reject) {

      mollie.payments.create({
          amount:      20.00,
          description: "Reservation code: ",
          redirectUrl: "https://www.website.com/",
          webhookUrl:  ""
        }, function(payment) {
              if (payment.error) reject(payment.error)
              else { resolve({
                  id: payment.id,
                  link: payment.getPaymentUrl(),
                  status: payment.status
                })
              }
      });

   });
 }

 return await asyncPayment();

}

我希望有人可以在这里帮助我...

I hope someone can help me out here...

推荐答案

您似乎错过了 async 函数仍然返回promise,而不是实际值的想法.因此,当您调用 create_booking_payment()时,您将得到一个承诺,即您需要将 .then()与或将 await 与.跨职能边界没有免费的午餐. await 允许您以类似同步的方式在函数内部进行编程,但仍然不允许您从函数中返回值.当您看起来好像要从 async 函数返回值时,实际上是在返回解析为该值的promise.

You seem to have missed that an async function still returns a promise, not the actual value. So, when you call create_booking_payment(), you are getting back a promise that you need to use either .then() with or await with. There's no free lunch across a function boundary. await allows you to program in a synchronous-like fashion inside a function, but still does not allow you to return the value from the function. When it looks like you're returning the value from the async function, you're actually returning a promise that resolves to that value.

因此,您可以使用 async await :

exports.create_booking = async function(req, res) {

   try{
      req.body.payment = await exports.create_booking_payment(req.body.total_amount);

      console.log(req.body.payment);

      var new_booking = new Booking(req.body);
      new_booking.save(function(err, booking) {
        if (err)
          res.status(500).send(err);
        else 
          res.json(booking);
      });
   } catch(e) {
      res.status(500).send(err);
   } 
};

或使用 .then():

exports.create_booking = function(req, res) {

      exports.create_booking_payment(req.body.total_amount).then(payment => {    
          console.log(payment);
          req.body.payment = payment;
          var new_booking = new Booking(req.body);
          new_booking.save(function(err, booking) {
            if (err)
              res.status(500).send(err);
            else 
              res.json(booking);
         });
    }).catch(err => {
        res.status(500).send(err);
    });

};

注意,我还为这两种情况添加了更完整的错误处理.另外,如果您承诺"或对 .save()方法使用已经承诺的接口,则此代码将更加简洁.我非常不喜欢在基于Promise的代码中使用普通的回调异步代码,因为它最终会导致重复的错误处理(就像您在本例中看到的那样).

Note, I also added more complete error handling to both scenarios. Also, this code would be a lot cleaner if you "promisfied" or used an already promisified interface for your .save() method. I strongly dislike using plain callback async code inside of promise-based code because it ends up duplicating error handling (like you see in this case).

此外, create_booking_payment()不必是 async 或使用 await ,因为您所需要做的就是返回您的承诺已经知道该怎么做:

Also, create_booking_payment() doesn't need to be async or use await since all you need it to do is to return your promise which it already knows how to do:

exports.create_booking_payment = function() {

  return new Promise (function(resolve, reject) {

      mollie.payments.create({
          amount:      20.00,
          description: "Reservation code: ",
          redirectUrl: "https://www.website.com/",
          webhookUrl:  ""
        }, function(payment) {
              if (payment.error) reject(payment.error)
              else { resolve({
                  id: payment.id,
                  link: payment.getPaymentUrl(),
                  status: payment.status
                })
              }
      });

   });

}

这篇关于如何从另一个函数内的Promise返回值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆