2017-11-10 173 views
0

我正在尝试编写一个测试IOTA nano事务的简短应用程序。当谈到异步编程时,我是一个noob。请原谅我没有看到明显的。Nodejs表示从回调到对象的赋值

我的问题:如何在正确的时刻将回调函数的值赋值给对象。

下面的代码的说明: 这些是我的nodejs快递应用程序的片段。我使用控制器,路由器和我的钱包模型。

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

然而,可能是因为回调函数是所有其他功能后执行,我 只是不能找到一个方法来写这篇文章我的钱包对象,并接受它在我 showPaymentInstructionsAction显示它。

我的解释至今:

  1. 随着(回调).bind(这个)我大概可以分配值到 对象。
  2. 该值从未显示在showPaymentInstructionsAction(当前是一个简单的网页)中,因为该页面在执行回调函数之前呈现为异步性质。

你能帮助我吗?

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

  2. 我不应该尝试从回调中收到一个值吗?

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

最好的问候, 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); 
}; 

回答

4
  1. 是的,你在这里缺少的基本格局。
  2. 是的,你不能从回调中返回一个值。
  3. 可以肯定的是阅读更多有关承诺here

您可以删除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

+0

我试图让这个运行。在Promise中,我不能用“this”访问对象,例如它不会识别“this.iota_node”。 – Stowoda

+1

你可以,你可以在这里使用箭头功能。我编辑了代码,请看看。箭头功能允许您访问外部范围。 –

+1

您可以查看一个片段,以供我在最后保存的参考。 –