2017-11-24 8 views
0

私は非同期プログラミングと約束についてたくさんの質問があることを知っていますが、別の関数で返されている約束をどのように返すべきかを理解するためには、この特定のコードの例が本当に必要です。別の関数の中にある約束から値を返すには?

私には2つの機能があります。最初のルートは、ルートに行くときに呼び出されます。このルートは支払いリンクを作成し、データベースに予約を保存する必要があります。

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); 
     }); 

}; 

ただし、支払いリンクの作成は非同期メソッドで行われます。私の最初の問題は、メソッドコールバック関数内の支払いにしかアクセスできないということでした。

今私は、プロミスが作成され解決された別の(非同期)メソッドの中にメソッドをラップしました。このメソッドは、awaitステートメントで最初のメソッドに返されていますが、これはすべて「Promise {}」を返します。

これは、約束が解決される前にメソッドが返されているためです。しかし、私はなぜこれが理解できません。私の前提は、非同期関数が完了する前に 'await'ステートメントがメソッドを返すのを待つことです。

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(); 

} 

私はあなたがasync機能はまだ約束ではなく、実際の値を返すことを見逃しているように見える

答えて

4

...誰かがここに私を助けることができると思います。したがって、create_booking_payment()に電話をするときは、.then()またはawaitのいずれかを使用する必要があるという約束が返ってきます。関数の境界を越えてフリーランチはありません。 awaitは、関数内で同期的なやり方でプログラムすることができますが、関数から値を返すことはできません。 async関数から値を返すように見える場合、実際にはその値に解決する約束を返しています。

だから、あなたはasyncawaitでこれを行うだろう:

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()メソッドのための "promisfied"または既にpromisifiedなインターフェイスを使用した場合、このコードはもっと洗練されたものになります。私は、エラーハンドリングの複製を終了するので(この場合のように)、プロミスベースのコード内でプレーンコールバック非同期コードを使用することを強く嫌っています。


また、create_booking_payment()asyncになるか、あなたはそれを行うために必要なのは、それがすでにやる方法を知っているあなたの約束を返すことですので、awaitを使用する必要はありません。

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 
       }) 
       } 
     }); 

    }); 

} 
+0

、これと 、 'exports.create_booking_payment'関数は' async'を持つ必要はなく、戻り値は 'await'を必要としません。それは約束を返すからです。 – Kaddath

+0

@Kaddath - そうです、それを追加しました。 – jfriend00

+0

ありがとうございました!これは完全に機能しました。 – NvdB31

関連する問題