【问题标题】:Nodejs express assign value from callback to objectNodejs将回调中的值分配给对象
【发布时间】:2018-04-24 02:44:42
【问题描述】:

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

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

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

当使用 iota 库请求服务 (iri) 时,我只能使用异步函数。在以下情况下,我想为我的钱包接收一个 IOTA 地址。这适用于服务,我可以通过将生成的地址写入 console.log 来测试它。

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

到目前为止我的解释:

  1. 使用 (callback).bind(this) 我可以将值分配给 目的。
  2. 该值从未显示在 showPaymentInstructionsAction(当前是一个简单的网页)中,因为该页面是在回调函数执行之前呈现的异步性质。

你能帮我什么忙?

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

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

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

最好的问候, 彼得对象

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

【问题讨论】:

    标签: javascript node.js asynchronous callback


    【解决方案1】:
    1. 是的,您在这里缺少基本模式。
    2. 是的,您不能从回调中返回值。
    3. 你可以阅读更多关于 Promise 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

    演示sn-p

    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。

    【讨论】:

    • 我正在尝试运行它。在 Promise 中,我无法使用“this”访问对象,例如它不会识别“this.iota_node”。
    • 可以,这里可以使用箭头功能。我编辑了代码,请看一下。箭头函数允许您访问外部范围。
    • 您可以查看一个 sn-p 以供我在最后保留的参考。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-27
    • 1970-01-01
    • 2017-06-15
    • 2019-07-07
    • 1970-01-01
    • 2017-01-26
    相关资源
    最近更新 更多