首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >nodejs中的此方法正在返回一个未定义的对象。

nodejs中的此方法正在返回一个未定义的对象。
EN

Stack Overflow用户
提问于 2020-04-17 03:55:47
回答 1查看 272关注 0票数 0

我之前问过这个问题,它与这个问题( 如何从异步调用返回响应? )有关联,但它不能解决我的问题

我对node.js非常陌生,我遇到了一些错误,我无法处理,也无法找到我理解的任何帮助。我用快递生成器来初始化应用程序。我试图发送和对象,我通过一个api调用到前端。我编写了一个类"StockClass.js“,其中包含一个函数makeApiCall(),该函数进行调用并返回对象。但是当我在路由器中调用这个函数时,我会得到“未定义”。这是代码

代码语言:javascript
复制
//==== StockClass.js ===

const yahooFinance = require("yahoo-finance");
class stockClass {
    static makeApiCall(symbol) {
        yahooFinance.quote(
            {
                symbols: [symbol],
                modules: ["price", "summaryDetail"],
            },
            function (err, quotes) {
                if (err) { console.log(err) }
                console.log(quotes)
                return quotes;
            }
        );
    }
}

module.exports = stockClass;

//=====index.js======

const StockClass = require("../handlers/StockClass");

router.get("/new", function (req, res) {

   let quotes = StockClass.makeApiCall("AAPL");
   console.log(quotes);
   res.render('path', { quotes });
});

console.log中的StockClass.js正确地记录对象(引号),而index.js中的console.log记录“未定义”。

下面的链接解释了雅虎财务api调用。https://www.npmjs.com/package/yahoo-finance

==========================================================================

我还尝试使用中间件并将数据附加到响应对象,如下所示

代码语言:javascript
复制
//==========middleware=========

const yahooFinance = require("yahoo-finance");

module.exports = {

    makeApiCall: (symbol) => {
        return function (req, res, next) {
            yahooFinance.quote(
                {
                    symbols: [symbol],
                    modules: ["price", "summaryDetail"],
                },
                function (err, quotes) {
                    if (err) { console.log(err) }
                    res.stockObj = quotes;
                    console.log(res.stockObj);
                }
            );
            next();
        }
    }
}

//======= index.js =========
const handler = require("./handlers/stockUtils");

    router.get("/new", handler.makeApiCall("AAPL"), function (req, res) {

       let quotes = res.stockObj;
       console.log(quotes);
       res.render('path', { quotes });
    });

结果是一样的。中间件函数中的console.log记录正确的对象,但index.js中的console.log记录未定义。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-04-17 04:42:13

这是异步编程(非阻塞)的典型案例,来自同步编程背景(如pythonjavac等)--我也面临着理解javascript中代码流的问题。我花了一段时间,但一旦您掌握了javascript语言的行为方式,您将能够看到JS引擎如何解释您的代码以及如何执行它。以下是一些您可能觉得有用的链接:

不管怎样,有三种方法可以解决你的问题。

  1. 回调(旧方式)
  2. 承诺(有点新的方式)
  3. 异步/等待(最新方式)

回调方式

我已经简化了您的模块化代码,以等待异步操作完成,然后进行回调。我会让你再分割它,并使用它在快递或任何你正在使用的网页框架。

代码语言:javascript
复制
const yahooFinance = require("yahoo-finance");

class StockClass {
  static makeApiCall(symbol, callback) {
    yahooFinance.quote(
      {
        symbols: [symbol],
        modules: ["price", "summaryDetail"],
      },
      function (err, quotes) {
        if (err) {
          console.log(err);
        }
        callback(quotes);
      }
    );
  }
}

function toBeExecutedWhenDone(data) {
  console.log(data);
}

// since its a static function we are calling it directly from Class instance
StockClass.makeApiCall("AAPL", toBeExecutedWhenDone); // this function can be your response

在上面的代码中,只有当您有数据/引号时(或者您可以说异步操作完成时),您才会执行或返回响应。稍后我会让你探索更多。

承诺方式

承诺允许你回报一些叫做承诺的东西!承诺将在异步操作完成后得到解决。下面是您的代码。

代码语言:javascript
复制
const yahooFinance = require("yahoo-finance");

class StockClass {
  static makeApiCall(symbol) {
    return new Promise((resolve, reject) => {
      yahooFinance.quote(
        {
          symbols: [symbol],
          modules: ["price", "summaryDetail"],
        },
        function (err, quotes) {
          if (err) {
            reject(err);
          }
          resolve(quotes);
        }
      );
    });
  }
}

// since its a static function we are calling it directly from Class instance
StockClass.makeApiCall("AAPL")
  .then((data) => console.log(data)) // you could add your return your response instead of console log.
  .catch((err) => console.error(err));

异步等待方式!

异步等待要求您的函数使用async关键字声明。您可以查看速成指南,因为它已经支持异步函数。下面是片段的样子。

代码语言:javascript
复制
const yahooFinance = require("yahoo-finance");

class StockClass {
  static makeApiCall(symbol) {
    return new Promise((resolve, reject) => {
      yahooFinance.quote(
        {
          symbols: [symbol],
          modules: ["price", "summaryDetail"],
        },
        function (err, quotes) {
          if (err) {
            reject(err);
          }
          resolve(quotes);
        }
      );
    });
  }
}

async function giveMeQuotes() {
  try {
    const stock = await StockClass.makeApiCall("AAPL");
    console.log(stock); // this gets executed when above async operation finishes
  } catch (error) {
    console.error(error);
  }
}

// executing to show that it works...
giveMeQuotes();

希望能帮上忙!祝好运!

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61263895

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档