
如题,遇到一个问题,在一个回调方法中多次回调获取的请求尽然是第一次请求的数据,具体请看下文。
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 年 6 月 9 日 我看你上来就 var self = this, 你有想过你这个地方 this === global 吗? |
3 oott123 2017 年 6 月 9 日 有个简单的方法是改成 var self = {}; 试试。。。 |