当我收到请求时,我希望它生成一个4个字符的代码,然后检查它是否已存在于数据库中。如果是,则生成新代码。如果没有,请添加并继续。这就是我到目前为止所做的:
var code = "";
var codeFree = false;
while (! codeFree) {
var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
var code = "";
for (var i = 0; i < 4; i++) {
var rand = Math.floor(Math.random() * chars.length);
console.log(rand);
code += chars.charAt(rand);
}
console.log("Code: %s generated.", code);
client.execute("select * from codes where code=" + code, function(err, result) {
if (! err) {
if (result.rows.length > 0) {
codeFree = false;
} else {
codeFree = true;
}
} else {
console.log('DB ERR: %s', err);
}
console.log(codeFree);
});
console.log('here');
}
这几乎没有我想做的事情。我怎么能处理这样的事情?
答案 0 :(得分:2)
您正在执行异步任务。
当你的程序中有异步任务时,你需要有一个回调函数,它将以所需的值作为参数调用。
当你找到免费代码时,你调用该函数并将代码作为参数传递,否则,再次调用 <img src=assets/img/Guild/0000$logo/$logoColor.png class=\"avatar img-responsive\" style=\"margin: 0 auto; position: absolute; z-index: 10;\">
<img src=assets/img/Guild/0000$logoBG/$logoBGColor.png class=\"avatar img-responsive\" style=\"margin: 0 auto; position: absolute; z-index: -1;\">
函数并将相同的回调传递给它。虽然您可能会考虑发生错误的情况。如果您的db调用失败,则永远不会调用您的回调。最好使用getFreeCode
/ throw
机制或将另一个参数传递给您的回调。
你可以通过这种方式实现你需要做的事情:
catch
答案 1 :(得分:2)
我建议你研究两种替代方法来帮助处理异步代码。
使用生成器需要使用--harmony标志运行最新版本的节点。我推荐生成器的原因是因为您可以编写按预期方式流动的代码。
var x = yield asyncFunction();
console.log('x = ' + x);
在记录x之前,前面的代码将获得x的值。
在没有让出console.log的情况下,在async函数完成获取x的值之前会写出x。
您的代码可能看起来像生成器:
var client = {
execute: function (query) {
var timesRan = 0;
var result = [];
return function () {
return setTimeout(function () {
result = ++timesRan < 4 ? ['length_will_be_1'] : [];
return result;
},1);
};
}
};
function* checkCode () {
var code;
var codeFree = false;
while(!codeFree) {
var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
code = "";
for (var i = 0; i < 4; i++) {
var rand = Math.floor(Math.random() * chars.length);
console.log(rand);
code += chars.charAt(rand);
}
console.log("Code: %s generated.", code);
try {
var result = yield client.execute("select * from codes where code="+code);
codeFree = result.rows.length > 0 ? false : true;
}catch(e) {
console.log('DB ERR: %s', err);
} finally {
console.log(codeFree);
}
console.log('here');
}
}
checkCode().next();
您将离开客户端对象。我只是添加了一个用于伪造异步调用的工作示例。
如果你必须使用旧版本的节点或不喜欢yield语法,那么promises可能是一个值得的选择。
有许多承诺库。我推荐promises的原因是你可以编写符合预期的代码:
asyncGetX()
.then(function (x) {
console.log('x: ' + x);
});
在记录x之前,前面的代码将获得x的值。
它还允许您链接异步函数并按顺序运行它们:
asyncFunction1()
.then(function (result) {
return asyncFunction2(result)
})
.then(function (x) { /* <-- x is the return value from asyncFunction2 which used the result value of asyncFunction1 */
console.log('x: ' + x);
});
您的代码看起来像是&#39; q&#39;承诺图书馆:
var Q = require('q');
var client = {
timesRan: 0,
execute: function (query, callback) {
var self = this;
var result = {};
setTimeout(function () {
console.log('self.timesRan: ' + self.timesRan);
result.rows = ++self.timesRan < 4 ? ['length = 1'] : [];
callback(null, result);
},1);
}
};
function checkCode () {
var deferred = Q.defer();
var codeFree = false;
var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
var code = "";
for (var i = 0; i < 4; i++) {
var rand = Math.floor(Math.random() * chars.length);
console.log('rand: %s', rand);
code += chars.charAt(rand);
}
console.log("Code: %s generated.", code);
client.execute("select * from codes where code="+code, function(err, result) {
console.log('err: '+err+', result: ' + JSON.stringify(result));
console.log('result.rows.length: ' + result.rows.length);
if(!err) {
if(result.rows.length > 0) {
codeFree = false;
console.log('result.rows: %s, codeFree: %s', result.rows, codeFree);
checkCode();
} else {
codeFree = true;
console.log('line 36: codeFree: ' + codeFree);
deferred.resolve(code);
}
}else {
console.log('DB ERR: %s', err);
deferred.reject(err);
}
console.log(codeFree);
});
console.log('waiting for promise');
return deferred.promise;
}
checkCode()
.then(function (code) {
console.log('success with code: ' + code);
})
.fail(function(err) {
console.log('failure, err: ' + err);
});
此处也省略了客户端对象。我只是添加了一个用于伪造异步调用的工作示例。
Promise和generator绝对需要一段时间才能习惯。这是值得的,因为它们使代码最终比使用嵌套回调编写的代码更容易理解。