我是Node.js的新手,很抱歉。
在我的代码中,我使用的是某些服务的API。基本上它是很多回调。这些回调提供了我需要在另一个回调中使用的服务的值。
如果是同步方式,那么我会写如下:
var value1 = 10;
var value2 = 0;
var value3 = '';
var value4 = '';
api.method1((error, data) => {
if (error) {
// some code
}
value2 = data.value1FromApi / value1;
});
if (value2 > 0) {
api.method2(value2, value1, (error, response) => {
if (error) {
// some code
}
value3 = response.value2FromApi;
value4 = response.value3FromApi;
});
// Check status
for (var i = 0; i < 10; i++) {
if (value4 !== 'some status') {
api.method3(value3, (error, response) => {
value4 = response.value4FromApi;
});
// wait(1000);
}
else {
break;
}
}
if (value4 !== 'some status') {
api.method4(value3, (error, response) => {
});
}
else {
// similar code as above
}
}
我知道这是错误的代码,因为在第一次回调value2
之后未完成。
告诉我需要应用哪些技术或哪些技术才能解决该回调序列?
答案 0 :(得分:5)
您需要以异步方式处理此问题。你可以试试这个:
api.method1((error, data) => {
if (error) {
// some code
}
value2 = data.value1FromApi / value1;
if (value2 > 0) {
api.method2(value2, value1, (error, response) => {
if (error) {
// some code
}
value3 = response.value2FromApi;
value4 = response.value3FromApi;
// Check status
for (var i = 0; i < 10; i++) {
if (value4 !== 'some status') {
api.method3(value3, (error, response) => {
value4 = response.value4FromApi;
if (value4 !== 'some status') {
api.method4(value3, (error, response) => {
});
}
else {
// similar code as above
}
});
}
else {
break;
}
}
});
}
});
基本上所有的回调都必须嵌套在彼此之中
答案 1 :(得分:1)
value2
是undefined
,因为它是在异步函数中分配的。 value2
的使用发生在函数执行之前。
您可以获得有关JavaScript EventLoop的一些知识,以便更好地理解。
PS。有许多方法可以处理异步函数和回调地狱,例如Promise,async,co,async & await in node 8。
请查看http://callbackhell.com/了解详情。
答案 2 :(得分:1)
为了链接许多请求,您需要使用promises。
var method3CalledTimes = 0;
const api = { // Replace api with real API calls
method1: function() {
return Promise.resolve({ value1FromApi: 1 });
},
method2: function() {
return Promise.resolve({ value2FromApi: 2, value3FromApi: 3 });
},
method3: function() {
if (method3CalledTimes++ <= 3) // for demo
return Promise.resolve({ status: "not-correct-status-yet" });
return Promise.resolve({ status: "correct-status" });
},
method4: function() {
return Promise.resolve("Success");
}
};
var value1 = 10,
value2,
value3,
value4;
api.method1()
.then(function(data) {
value2 = data.value1FromApi / value1;
if (value2 <= 0)
return Promise.reject("v2 is non-positive");
return api.method2();
})
.then(function(data) {
value3 = data.value2FromApi;
value4 = data.value3FromApi;
return Promise.all([api.method3(), api.method4()]);
})
.then(function() {
return new Promise(function(resolve, reject) {
var tryCount = 10;
function checkStatus()
{
console.log("Trying to call method3(). Attempts left: " + tryCount);
api.method3()
.then(function(data) {
console.log("Status response: " + data.status);
if (data.status === "correct-status") {
console.log("Valid status, resolving...");
resolve(data.status); // status did change
} else {
if (tryCount-- <= 0) { // if no tries left
console.log("Invalid status, no attempts left. Failing...");
reject("statusnotchanged"); // status didn't change after N attempts
} else { // if we have tries
console.log("Invalid status, we have attempts. Trying again...");
setTimeout(checkStatus, 1000); // try again in 1 second
}
}
})
.catch(reject); // if error - reject
}
checkStatus(); // call once, then it will call itself with setTimeout
});
})
.then(function(newStatus) {
console.log("Complete! New status = " + newStatus);
})
.catch(function(r) {
if (reason === "statusnotchanged") {
// handle this specific reason if needed
}
console.error(r);
});
&#13;
这段代码只是一个例子,它显示了这个想法。您的代码示例意图非常不明确,因此我无法对其进行优化。
了解Promise如何使错误处理变得更容易。链中的任何拒绝都将导致执行.catch
。尝试将value1
设置为0以查看会发生什么。
答案 3 :(得分:1)
我在学习node.js时遇到了同样的问题。
我有一个调用外部API的文件,当用户请求路由时,我的服务器将响应作为json对象发送。
var connection {user:“user”,密码:“password”} //这只是我的连接对象的一个例子
exports.getUsers = function(){
return new Promise(function(resolve, reject){
var params = {search_string:""};
var users = [];
connection.Users.get(params, function(error, response){
var user;
for(let i = 0; i < response.data.length; i++)
{
if(response.data[i].name=="user"
{
user = response.data[i];
}
}
users.push({user});
resolve(users); //return the user object
});
});
};
const request = require('./requests.js'); //file with my external api calls
app.get('/users', function(req, res){
requests.getUsers()
.then(function(users){
res.contentType('application/json');
res.send(JSON.stringify(users));
})
.catch(function(err){
console.log(err);
});
});
如果您使用PROMISE,该功能将一直等到您继续之前获得所需的值。
。您可以根据需要向调用api的用户发送结果。
在MDN文档中,您可以找到关于JS的所有内容,它非常有用。
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
阅读更多关于promises的内容我发现了其他链接,它也很有用: http://exploringjs.com/es6/ch_promises.html