我之前问过这个问题,它与这个问题( 如何从异步调用返回响应? )有关联,但它不能解决我的问题
我对node.js非常陌生,我遇到了一些错误,我无法处理,也无法找到我理解的任何帮助。我用快递生成器来初始化应用程序。我试图发送和对象,我通过一个api调用到前端。我编写了一个类"StockClass.js“,其中包含一个函数makeApiCall(),该函数进行调用并返回对象。但是当我在路由器中调用这个函数时,我会得到“未定义”。这是代码
//==== 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
==========================================================================
我还尝试使用中间件并将数据附加到响应对象,如下所示
//==========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记录未定义。
发布于 2020-04-17 04:42:13
这是异步编程(非阻塞)的典型案例,来自同步编程背景(如python、java、c等)--我也面临着理解javascript中代码流的问题。我花了一段时间,但一旦您掌握了javascript语言的行为方式,您将能够看到JS引擎如何解释您的代码以及如何执行它。以下是一些您可能觉得有用的链接:
不管怎样,有三种方法可以解决你的问题。
回调方式
我已经简化了您的模块化代码,以等待异步操作完成,然后进行回调。我会让你再分割它,并使用它在快递或任何你正在使用的网页框架。
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在上面的代码中,只有当您有数据/引号时(或者您可以说异步操作完成时),您才会执行或返回响应。稍后我会让你探索更多。
承诺方式
承诺允许你回报一些叫做承诺的东西!承诺将在异步操作完成后得到解决。下面是您的代码。
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关键字声明。您可以查看速成指南,因为它已经支持异步函数。下面是片段的样子。
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();希望能帮上忙!祝好运!
https://stackoverflow.com/questions/61263895
复制相似问题