async.js 函数排序
async.js Ordering of functions
所以我无法让一个 javascript 函数在下一个函数开始之前完成。我花了很多时间尝试使用其他 Whosebug 帖子中描述的回调方法。我可以获得使用超时工作但无法使其与我的 API 请求一起工作的简单示例。我偶然发现 async.js
并认为使用 async.series
可能是一个让我的两个函数一个接一个执行的好主意。所以我尝试了这种方法,但是我似乎仍然遇到第一个函数执行时间稍长的问题(这很好),但是执行过程通过了这个函数而不是等待它结束。我觉得我有某种误解,因为我尝试了几种方法但无济于事。
奇怪的是,当运行 server.js
时,它进入了第一个函数,但在请求完成之前就离开了async.series()
函数。当我在 tokenReq()
内部打印时,我可以看到请求成功,因为令牌代码已成功返回,但是随着执行的进行,这种情况发生得很晚。输出如下所示。
server.js:
var access_code;
async.series([
function() {
access_code = queries.data.tokenReq(code);
console.log("Finished inside function 1");
},
function() {
console.log("\n Starting function 2 \n");
if (access_code === "error") {
res.json("An error has occured");
} else {
var response = queries.data.messagesReq(access_code);
res.json(response);
}
}
],
function(err, access_code) {
});
console.log("Outside");
queries.js:
tokenReq: function(code) {
var tokenUrl = "https://login.microsoftonline.com/common/oauth2/v2.0/token";
var form = {
code: code,
client_id: "__ID__",
redirect_uri: "__Site__/",
grant_type: "authorization_code",
client_secret: "__Secret__",
};
var formData = querystring.stringify(form);
var contentLength = formData.length;
request({
headers: {
'Content-Length': contentLength,
'Content-Type': 'application/x-www-form-urlencoded'
},
uri: tokenUrl,
body: formData,
method: 'POST'
}, function (error, response, body) {
if (error != "null") {
var access_token = JSON.parse(body).access_token;
console.log("\n INSIDE FUNCTION REQUEST, Token: " + access_token + " \n");
return access_token;
} else {
console.log('error:', error); // Print the error if one occurred
console.log('statusCode:', response && response.statusCode); // Print the response status code if a response was received
// console.log('body:', body); // Print the HTML for the Google homepage.
return "error";
}
});
},
输出:
Finished inside function 1
Outside
INSIDE FUNCTION REQUEST, Token: 8Swhd.......
你在这里错过了一个重点。由于 node.js 是异步的,所以应该没有办法知道函数何时完成执行。这就是为什么我们指定回调,以便调用函数在完成执行时知道调用谁。一旦你有了回调函数,你就可以用 async
模块强制执行 series/parallel/waterfall 行为。
tokenReq: function(code, cb) {
var tokenUrl = "https://login.microsoftonline.com/common/oauth2/v2.0/token";
var form = {
code: code,
client_id: "__ID__",
redirect_uri: "__Site__/",
grant_type: "authorization_code",
client_secret: "__Secret__",
};
var formData = querystring.stringify(form);
var contentLength = formData.length;
request({
headers: {
'Content-Length': contentLength,
'Content-Type': 'application/x-www-form-urlencoded'
},
uri: tokenUrl,
body: formData,
method: 'POST'
}, function (error, response, body) {
if (error != "null") {
var access_token = JSON.parse(body).access_token;
console.log("\n INSIDE FUNCTION REQUEST, Token: " + access_token + " \n");
return cb(null, access_token);
} else {
console.log('error:', error); // Print the error if one occurred
console.log('statusCode:', response && response.statusCode); // Print the response status code if a response was received
// console.log('body:', body); // Print the HTML for the Google homepage.
return cb(new Error("whatever"));
}
});
},
现在,你可以使用里面的回调了server.js
var access_code;
async.series([
function(cb) {
return queries.data.tokenReq(code, cb);
},
function(access_code, cb) {
console.log("\n Starting function 2 \n");
if (access_code === "error") {
res.json("An error has occured");
} else {
var response = queries.data.messagesReq(access_code);
res.json(response);
}
// do whatever you want after this
return cb();
}
],
function(err, access_code) {
if (err) {
console.log(err);
}
// wrap your logic around a function and call the correspoding callback here
});
所以我无法让一个 javascript 函数在下一个函数开始之前完成。我花了很多时间尝试使用其他 Whosebug 帖子中描述的回调方法。我可以获得使用超时工作但无法使其与我的 API 请求一起工作的简单示例。我偶然发现 async.js
并认为使用 async.series
可能是一个让我的两个函数一个接一个执行的好主意。所以我尝试了这种方法,但是我似乎仍然遇到第一个函数执行时间稍长的问题(这很好),但是执行过程通过了这个函数而不是等待它结束。我觉得我有某种误解,因为我尝试了几种方法但无济于事。
奇怪的是,当运行 server.js
时,它进入了第一个函数,但在请求完成之前就离开了async.series()
函数。当我在 tokenReq()
内部打印时,我可以看到请求成功,因为令牌代码已成功返回,但是随着执行的进行,这种情况发生得很晚。输出如下所示。
server.js:
var access_code;
async.series([
function() {
access_code = queries.data.tokenReq(code);
console.log("Finished inside function 1");
},
function() {
console.log("\n Starting function 2 \n");
if (access_code === "error") {
res.json("An error has occured");
} else {
var response = queries.data.messagesReq(access_code);
res.json(response);
}
}
],
function(err, access_code) {
});
console.log("Outside");
queries.js:
tokenReq: function(code) {
var tokenUrl = "https://login.microsoftonline.com/common/oauth2/v2.0/token";
var form = {
code: code,
client_id: "__ID__",
redirect_uri: "__Site__/",
grant_type: "authorization_code",
client_secret: "__Secret__",
};
var formData = querystring.stringify(form);
var contentLength = formData.length;
request({
headers: {
'Content-Length': contentLength,
'Content-Type': 'application/x-www-form-urlencoded'
},
uri: tokenUrl,
body: formData,
method: 'POST'
}, function (error, response, body) {
if (error != "null") {
var access_token = JSON.parse(body).access_token;
console.log("\n INSIDE FUNCTION REQUEST, Token: " + access_token + " \n");
return access_token;
} else {
console.log('error:', error); // Print the error if one occurred
console.log('statusCode:', response && response.statusCode); // Print the response status code if a response was received
// console.log('body:', body); // Print the HTML for the Google homepage.
return "error";
}
});
},
输出:
Finished inside function 1
Outside
INSIDE FUNCTION REQUEST, Token: 8Swhd.......
你在这里错过了一个重点。由于 node.js 是异步的,所以应该没有办法知道函数何时完成执行。这就是为什么我们指定回调,以便调用函数在完成执行时知道调用谁。一旦你有了回调函数,你就可以用 async
模块强制执行 series/parallel/waterfall 行为。
tokenReq: function(code, cb) {
var tokenUrl = "https://login.microsoftonline.com/common/oauth2/v2.0/token";
var form = {
code: code,
client_id: "__ID__",
redirect_uri: "__Site__/",
grant_type: "authorization_code",
client_secret: "__Secret__",
};
var formData = querystring.stringify(form);
var contentLength = formData.length;
request({
headers: {
'Content-Length': contentLength,
'Content-Type': 'application/x-www-form-urlencoded'
},
uri: tokenUrl,
body: formData,
method: 'POST'
}, function (error, response, body) {
if (error != "null") {
var access_token = JSON.parse(body).access_token;
console.log("\n INSIDE FUNCTION REQUEST, Token: " + access_token + " \n");
return cb(null, access_token);
} else {
console.log('error:', error); // Print the error if one occurred
console.log('statusCode:', response && response.statusCode); // Print the response status code if a response was received
// console.log('body:', body); // Print the HTML for the Google homepage.
return cb(new Error("whatever"));
}
});
},
现在,你可以使用里面的回调了server.js
var access_code;
async.series([
function(cb) {
return queries.data.tokenReq(code, cb);
},
function(access_code, cb) {
console.log("\n Starting function 2 \n");
if (access_code === "error") {
res.json("An error has occured");
} else {
var response = queries.data.messagesReq(access_code);
res.json(response);
}
// do whatever you want after this
return cb();
}
],
function(err, access_code) {
if (err) {
console.log(err);
}
// wrap your logic around a function and call the correspoding callback here
});