如题,遇到一个问题,在一个回调方法中多次回调获取的请求尽然是第一次请求的数据,具体请看下文。
1.Tools.shortId()
//用来生成 8 位的数字 id
var redis = new IoRedis(config.redis.dev);
var lock = require("redis-lock")(redis, 50);
exports.shortid = function (key, retries, callback) {
var self = this;
if (typeof retries === "function" && !callback) {
self.cb = retries;
self.retries = 5;
} else if (typeof retries === "number") {
self.retries = retries;
self.cb = callback;
} else {
throw new Error('illegal parameters');
}
//生成 id
var getId = function () {
var num = new Array(8);
var c;
for (var i = 0; i < 8; i++) {
num[i] = Math.floor(Math.random() * 9 + (i === 0 ? 1 : 0));
c = num[i];
for (var j = 0; j < i; j++) {
if (num[j] === c) {
i--;
break
}
}
}
return num.toString().replace(/,/g, '');
};
var setbit = function (id, callback) {
redis.setbit('shortid:' + key, id, 1, callback);
};
var getbit = function (id, callback) {
redis.getbit('shortid:' + key, id, callback);
};
var retry = function (cb) {
//获取锁
lock('shortidt:lock:' + key, function (done) {
var id = getId();
getbit(id, function (err, ret) {
if (err) {
cb(err, null);
} else {
if (ret === 0) {
setbit(id, function (err, ret) {
if (err) {
cb(err, null);
} else {
done(function () {
cb(null, parseInt(id));
});
}
});
} else {
cb(null, null);
}
}
});
});
};
var _num = 0;
var intervalId = setInterval(function () {
retry(function (err, id) {
if (!id) {
if (_num === self.retries) {
clearInterval(intervalId);
self.cb(null, null);
} else {
_num = _num + 1;
}
} else {
clearInterval(intervalId);
self.cb(err, id);
}
});
}, 50);
};
2.module
//mongoose schema
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var UserSchema = new Schema({
loginid: { type: Schema.Types.ObjectId },
id: { type: Schema.Types.Number },
loginname: { type: String },
email: {type: String },
})
3.proxy
exports.saveUser = function (data, callback) {
var user = new User(data);
Tool.shortid(SHORTID_KEY, 10, function (err, id) {
if(err || !id) {
console.error("failed to get shortid. > ", err);
callback(err, id);
}else{
user.loginid = new mongoose.Types.ObjectId(id);
user.id = id;
console.log("email::" + user.email);
user.save(callback);
}
});
})
在同时处理多个请求时,发现输出的 email 结果总是第一个请求的 email 数据值。不知为何,还请各位帮忙解惑
1
vainly OP /**
* Created by chaclus on 2017/6/9. */ var IoRedis = require('ioredis'); var redis = new IoRedis(dev: { host: '127.0.0.1', port: 6379, password: 'root' }); var lock = require("redis-lock")(redis, 50); var shortid = function (key, retries, callback) { var self = this; if (typeof retries === "function" && !callback) { self.cb = retries; self.retries = 5; } else if (typeof retries === "number") { self.retries = retries; self.cb = callback; } else { throw new Error('illegal parameters'); } //生成 id var getId = function () { var num = new Array(8); var c; for (var i = 0; i < 8; i++) { num[i] = Math.floor(Math.random() * 9 + (i === 0 ? 1 : 0)); c = num[i]; for (var j = 0; j < i; j++) { if (num[j] === c) { i--; break } } } return num.toString().replace(/,/g, ''); }; var setbit = function (id, callback) { redis.setbit('shortid:' + key, id, 1, callback); }; var getbit = function (id, callback) { redis.getbit('shortid:' + key, id, callback); }; var retry = function (cb) { //获取锁 lock('app:shortidt:lock:' + key, function (done) { var id = getId(); getbit(id, function (err, ret) { if (err) { cb(err, null); } else { if (ret === 0) { setbit(id, function (err, ret) { if (err) { cb(err, null); } else { done(function () { cb(null, parseInt(id)); }); } }); } else { cb(null, null); } } }); }); }; var _num = 0; var intervalId = setInterval(function () { retry(function (err, id) { if (!id) { if (_num === self.retries) { clearInterval(intervalId); self.cb(null, null); } else { _num = _num + 1; } } else { clearInterval(intervalId); self.cb(err, id); } }); }, 50); }; var save = function (data) { shortid('user', 10, function (err, id) { if(err) { console.error("err:", err); }else{ console.log("id: "+ id+", email: " + data.email) } }); }; var user = ['a', 'b', 'c', 'd', 'e', 'f']; user.forEach(function (user) { save({name: user, email: user + "@gmail.com"}); }); 这个填写 redis 可以直接调试。 |
2
oott123 2017-06-09 13:18:20 +08:00 1
我看你上来就 var self = this, 你有想过你这个地方 this === global 吗?
|
3
oott123 2017-06-09 13:26:21 +08:00 1
有个简单的方法是改成 var self = {}; 试试。。。
|