Nodejs表示从回调到对象的赋值

时间:2017-11-10 19:45:34

标签: javascript node.js asynchronous callback

我正在尝试编写一个测试IOTA nano交易的简短应用。谈到异步编程,我是一个菜鸟。请原谅我没有看到明显的。

我的问题:如何在适当的时刻将回调函数中的值分配给对象。

以下代码说明: 这些是来自我的nodejs express app的片段。我使用控制器,路由器和我的钱包模型。

使用iota库请求服务(iri)时,我只能使用异步功能。在下面的例子中,我想收到钱包的IOTA地址。这适用于服务,我可以通过将生成的地址写入console.log来测试它。

然而,可能因为回调函数在所有其他函数之后执行,我 只是无法找到一种方法将其写入我的钱包对象并接收它以便在我的钱包中显示它 showPaymentInstructionsAction。

到目前为止我的解释

  1. 使用(回调).bind(this)我可以将值赋给 宾语。
  2. 该值永远不会显示在showPaymentInstructionsAction(当前是一个简单的网页)中,因为页面是在回调函数执行之前呈现的,因为它具有异步性。
  3. 你怎么能帮助我?

    1. 我是否错过了异步编程的基本模式?

    2. 我是否应该尝试从回调中接收值?

    3. 我应该了解Promise来解决这个问题吗?

    4. 最诚挚的问候, Peterobjec

      'use strict'
      
      class Wallet{
          constructor(iota_node, seed){
              this.seed = seed;
              this.receivingAddress = "empty";
              this.iota_node = iota_node;
          }
      
          generateAddress() {
      
              this.iota_node.api.getNewAddress(this.seed, {'checksum': true}, postResponse)
      
              function postResponse(error,address) {
                  if (!error) {
                      // callback won't assigned to my wallet object.
                      // I can probably use (function).bind(this); 
                      // But this doesn't solve the timing issue
                      this.receivingAddress = address
                      // console.log shows, the address is generated correctly
                      // but how can I get it into my object? and retreive it after it is written?
                      console.log("address callback: %s", this.receivingAddress)
                  }else{
                      console.log(e.message);
                  }
              }
          }
      
          getReceivingAddress(){
              // I never managed to get this filled by the callback
              console.log("in getReceivingAddress: %s", this.receivingAddress)
              return this.receivingAddress;
          }
      }
      
      // The controller
      var config = require('../config.js'),
          Wallet = require('./model_wallet'),
          IOTA = require('iota.lib.js');
      
      function orderRequestAction(req, res, next){
              // IOTA Reference Implementation 
              var iri = new IOTA({
                  'host': 'http://localhost',
                  'port': 14265
              });
              res.locals.wallet = new Wallet(iri, config.wallet.seed);
              res.locals.wallet.generateAddress()
      }
      
      function showPaymentInstructionsAction(req, res){
          res.render('paymentInstructions', {
              title:"payment instructions", 
              receivingAddress: res.locals.wallet.getReceivingAddress()
          })
      }
      
      
      // Router
      var controller = require('./controller');
      
      module.exports = function(app){
          app.post('/orderRequest', controller.orderRequestAction, controller.showPaymentInstructionsAction);
      };
      

1 个答案:

答案 0 :(得分:4)

  1. 是的,你在这里缺少基本模式。
  2. 是的,您无法从回调中返回值。
  3. 您可以查看有关Promise here
  4. 的更多信息

    您可以删除getReceivingAddress函数并使用generateAddress(),如下所示,

    generateAddress() {
        return new Promise((resolve, reject) => {
            this.iota_node.api.getNewAddress(this.seed, {'checksum': true}, (error,address) => {
                if (!error) {
                    // callback won't assigned to my wallet object.
                    // I can probably use (function).bind(this); 
                    // But this doesn't solve the timing issue
                    this.receivingAddress = address
                    // console.log shows, the address is generated correctly
                    // but how can I get it into my object? and retreive it after it is written?
                    console.log("address callback: %s", this.receivingAddress)
                    resolve(address); // You will get this while calling this function as shown next
                }else{
                    console.log(e.message);
                    reject(error);
                }
            })
    
    
        })
    }
    

    现在在调用该函数时,您需要在需要调用的地方使用它,

    ...
    generateRecievingAddress().then(function(address){
        // here address is what you resolved earlier
    }).catch(function(error){
        // error is what you rejected
    })
    

    我希望这能澄清你的疑虑。

    熟悉Promises时,您可能希望使用es7语法编写异步代码,使用async和await。您还可以阅读更多相关信息here

    演示片段

    class XYZ {
        constructor() {
            this.x = 15;
        }
    
        getX() {
            return new Promise((resolve, reject) => {
                if(true){
                    resolve(this.x);  // inside Promise
                }
                else{
                    reject(new Error("This is error"));
                }
            })
        }
    }
    
    const xObj = new XYZ();
    
    xObj.getX().then(function(x){
        console.log(x);
    }).catch(function(){
        console.log(error);
    })
    

    这将记录15。