【问题标题】:How to break some logic out of an async callback?如何打破异步回调中的一些逻辑?
【发布时间】:2019-12-11 13:07:14
【问题描述】:

我正在尝试使用请求中的回调方法进行 api 调用,但我是 web 开发的新手,目前我被困在 async 上。我有以下工作,但我想打破一些逻辑。例如,这是目前正在运行的内容

const request = require('request');

class GetAllData{

    constructor(){
        this.loadData();
    }

    // Gets all data from api query that I'll need to build everything else I'll need
    data(callback){
        request({'url':`https://definitely/a/url.json`, 'json': true }, function (error, response, body) {
            callback(body);
        });
    }

    loadData(cmrUrl){
        console.log("loadData");
        this.data(function(result){ console.log(result.foo.bar)});
    }
}

var moreData = new GetAllData();

这行得通,我可以做我需要做的两件事,即记录一些结果,并对结果进行小计算。但是,如果我想将此逻辑分解为其他函数,则会出现一些错误。

const request = require('request');

class GetAllData{

    constructor(){
        this.loadData();

    // Member variables
        this._subsetOne;
        this._thingICalculated;

    // Function call to print data outside of the async call.
        this.printData(this._subsetOne, this._thingICalculated);
    }

    // Gets all data from api query that I'll need to build everything else I'll need
    data(callback){
        request({'url':`https://definitely/a/url.json`, 'json': true }, function (error, response, body) {
            callback(body);
        });
    }

    loadData(cmrUrl){
        console.log("loadData");

                    // Set a class member variable
                    // ERROR: 'this' is undefined
                    this.data(function(result){ this._subsetOne = result.foo.bar)};

            // Call a member function, which calculates something, and then sets a member variable.
            this.calculateSomething = result;
            console.log(result);


        };
    }

    // Function which takes in result from async call, then calculates something.
    set calculateSomething(result){
        this._thingICalculated = result + 1;
    }

    printData(x, y){
        console.log(x,y);
    }
}

var moreData = new GetAllData();

从我一直在阅读的内容来看,我遇到的问题很常见,但我仍然不明白为什么这不起作用,因为调用是异步的,我只是想设置一个变量,或调用函数。我假设有一些方法可以要求成员变量设置和函数调用来等待异步请求的完成?


修复一次尝试

const request = require('request');

class GetAllData{

    constructor(){
        this.loadData();
        this._subset;
    }

    // Gets all data from api query that I'll need to build everything else I'll need
    data(callback){
        request({'url':`https://definitely.a.url/yep.json`, 'json': true }, function (error, response, body) {
            callback(body);
        });
    }

    loadData(cmrUrl){
        console.log("loadData");
        this.data(function(result){ this._subset = result
        this.getSubset()}.bind(this));
    }

    getSubset(){
        console.log(this._subset);
    }
}

var moreData = new GetAllData();

子集最终未定义。

【问题讨论】:

  • this 未定义,因为它被称为:callback(body)。您需要使用applycall 来设置this
  • 我不太明白你在问什么,但是在构造函数中使用异步操作(看起来你可能正在做)需要不同的设计模式才能让代码知道当那些异步的事情完成时。有关执行此操作的各种设计模式,请参阅 Asynchronous operations in a constructor
  • 您是如何使用 setter 将回调传递给请求的?您在某处的示例中看到了吗?
  • 谢谢,只是好奇;我也没见过。这对我来说似乎有点令人费解,但这并不是真正的问题。
  • 现在你遇到了不同的问题。在您调用moreData.getSubset() 时,甚至还没有调用异步函数的回调函数。我建议您阅读:How do I return the response from an asynchronous call?

标签: javascript node.js asynchronous callback request


【解决方案1】:

在构造函数中,您必须将任何使用this 的成员方法绑定到自身。所以在调用loadData之前:

this.loadData = this.loadData.bind(this);

似乎this.data 将在loadData 中获得自己的范围,这就是为什么this 在该函数内返回未定义的原因。因此,您还必须将 this.data 绑定到 this(您的类实例)。

对任何访问this 的方法执行相同的操作。问题是默认情况下经典的 JavaScript 函数具有未定义的范围。 Arrow functions 但是会自动继承调用者的作用域。

【讨论】:

  • loadData 很好。问题是this.data 中的函数。那就是需要this绑定的那个。
  • 无论我添加this.loadData = this.loadData.bind(this),还是this.data = this.data.bind(this),我都会遇到同样的问题,即未定义。
  • @trueCamelType 它需要绑定在 this.data = function(){..}.bind(this) 上,因为您的设置器会触发 request 调用。 this.data 也没有吸气剂,所以 this.data.bind(this) 不应该工作。
  • @MinusFour 谢谢,我已经从 setter 更改了函数,因此减少了混乱,而且它真的不需要成为 setter。据我所知,我已经添加了另一个部分来实施修复。新的getSubset() 函数返回undefined
猜你喜欢
  • 2022-12-06
  • 1970-01-01
  • 2013-12-21
  • 2021-11-18
  • 2019-09-10
  • 2014-12-04
  • 1970-01-01
  • 2022-11-20
  • 2021-07-19
相关资源
最近更新 更多