简体   繁体   English

Node.js表达从回调到对象的赋值

[英]Nodejs express assign value from callback to object

I am trying to write a short app for testing IOTA nano transactions. 我正在尝试编写一个简短的应用程序来测试IOTA nano交易。 When it comes to asynchronous programming, I am a noob. 说到异步编程,我是菜鸟。 Please forgive me for not seeing the obvious. 请原谅我没有看到明显的事情。

My problem: How to assign a value from a callback function to an object at the right moment. 我的问题:如何在适当的时候将回调函数的值分配给对象。

Explanation of the code below: Those are fragments from my nodejs express app. 下面的代码解释:这些是我的nodejs express应用程序的片段。 I use a controller, router and my wallet model. 我使用控制器,路由器和钱包模型。

When requesting a service (iri) using the iota library I have only asynchronous functions at my disposal. 当使用iota库请求服务(iri)时,我只有异步功能可以使用。 In the case below, I want to receive an IOTA address for my wallet. 在以下情况下,我想收到我的钱包的IOTA地址。 This works well with the service, I can test it by writing the generated address to the console.log. 这与服务很好地配合,我可以通过将生成的地址写入console.log进行测试。

However, probably because the callback function is executed after all other functions, I just can't find a way to write this to my wallet object and receive it for displaying it in my showPaymentInstructionsAction. 但是,可能是因为回调函数是在所有其他函数之后执行的,所以我找不到将其写入我的钱包对象并接收它以在showPaymentInstructionsAction中显示它的方法。

My explanation so far: 到目前为止,我的解释是:

  1. With (callback).bind(this) I can probably assign the value to the object. 使用(callback).bind(this)我可能可以将值分配给对象。
  2. The value is never shown in the showPaymentInstructionsAction (currently a simple web page), because the page is rendered before the callback function is executed by it's asynchronous nature. 该值永远不会显示在showPaymentInstructionsAction(当前是一个简单的网页)中,因为该页面是在异步功能执行回调函数之前呈现的。

How can you help me? 你有什么可以帮我的吗?

  1. Do I miss a basic pattern in async programming? 我是否会错过异步编程中的基本模式?

  2. Should I not try to receive a value from a callback? 我不应该尝试从回调中接收值吗?

  3. Should I learn about Promise to solve this? 我应该了解Promise来解决这个问题吗?

Best Regards, Peterobjec 最好的问候,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. Yes you are missing basic pattern here. 是的,您在这里缺少基本模式。
  2. Yes, you can not return a value from callback. 是的,您不能从回调返回值。
  3. You can sure read more about Promise here 您可以在此处确定更多有关Promise的信息

You can remove getReceivingAddress function and use generateAddress() like this, 您可以删除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);
            }
        })


    })
}

Now while calling the function, you need to use it like this wherever you need to call, 现在,在调用该函数时,您需要在需要调用的地方使用该函数,

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

I hope this will clarify your doubts. 我希望这可以澄清您的疑问。

When you familiar with Promises, you might want to use es7 syntax for writing async code, using async and await. 当您熟悉Promises时,您可能想使用es7语法来编写异步代码,即使用async和await。 You can also read more about it here 您还可以在这里阅读更多信息

Demo snippet 演示片段

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

This will log 15. 这将记录15。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM