如何在nodejs / expressjs中运行多个函数?在php中它是直截了当的,在另一个之后调用一个函数但是节点中的这个回调业务令人困惑,我不断得到变量未定义的错误等等。这是我正在做的基本想法。
var express = require('express');
var request = require('request');
var app = express();
app.get('/user/:id', function(req, res) {
var id = req.params.id;
getInformation(id, function(info) {
res.send(info);
});
});
app.listen(3000);
getInformation(id, callback) {
var qty = makeExternalApiCall();
var color = secondFunction(id);
callback({quantity: qty, color: color});
}
makeExternalApiCall() {
request({uri: 'https://provider.com/api/stuff/'}, function(error, response, body) {
if (!error && response.statusCode == 200) {
return body.qty;
}
}
}
secondFunction(id) {
//look up color by id
var color = "blue";
return color;
}
答案 0 :(得分:4)
运行多个函数与在PHP中运行类似,除非它涉及异步函数。异步回调是一个可以随时调用的函数,不适用于return
关键字。以此回调为例:
var cb = function(arg) {
console.log(arg);
};
我们可以将这个回调函数传递给另一个函数,并从内部调用该函数调用cb()
:
function call(text, callback) {
callback(text);
};
var txt = 'a string';
call(txt, cb);
console.log('breakpoint');
上面的示例同步运行。因此执行顺序是:
call() -> cb()
console.log()
但是如果我们延迟函数或添加一个计时器(process.nextTick
等待函数的callstack为空,那么执行已经排队的函数):
function call(text, callback) {
process.nextTick(function() {
callback(text);
});
};
再次运行它,我们得到一个不同的执行顺序,因为cb()
在callstack为空之后排队等待运行(在console.log()
运行之后,它是空的):
call()
console.log()
-> cb()
大多数未定义的变量错误是由在设置之前访问变量引起的。例如,采用异步函数foo()
。
var data;
foo(function(bar) {
data = bar;
});
console.log(data);
可能在function(bar) { ... });
之后调用了回调console.log()
,这意味着console.log()
会在data
获得值之前运行。
对于您的特定问题,请求模块是异步的并使用回调,因此您不能在HTTP请求中使用返回值。要从回调函数中获取结果值,您需要将其传递给另一个回调函数。使用return
关键字将停止函数的执行。所以改变这个:
var options = {
uri: 'https://provider.com/api/stuff/'
};
function makeExternalApiCall() {
request(options, function(err, res, body) {
if (!err && res.statusCode == 200) {
return body.qty;
}
}
};
使用回调:
function makeExternalApiCall(callback) {
request(options, function(err, res, body) {
if (!err && res.statusCode == 200) {
callback(null, body.qty);
}
}
};
然后将使用该函数:
makeExternalApiCall(function(err, qty) {
// here is qty
});
所以你的路由代码可能看起来像这样,使用嵌套的回调:
function getInformation(id, callback) {
var color = secondFunction(id);
makeExternalApiCall(function(err, qty) {
callback({ quantity: qty, color: color });
});
};
app.get('/user/:id', function(req, res) {
var id = req.params.id;
getInformation(id, function(info) {
res.send(info);
});
});
答案 1 :(得分:0)
您还可以使用next()函数,这为您提供路径文件或路径文件中的模块化。
即使您不必担心异步和同步环境。
在回调中执行next(),它只会在回调完成后执行,或者在执行回调时执行条件。