var redis = require('redis');
var https = require("https");
var client = redis.createClient(6379, "127.0.0.1",{db:1});
//错误监听
client.on("error", function (err) {
console.log("Error " + err);
});
var tt;
client.get('accessToken',function (d,r) {
console.log(r);
return tt=r;
})
console.log(tt);//一直是undefined
exports.accessToken = tt;
exports.redis = redis;
exports.clients = client;
怎么让他同步执行赋值给tt,这样就不要每次都去获取accessToken了
1
1.Async/Await
2.
exports.accessToken = function(cb){
client.get('accessToken',function (d,r) {
cb(d,r);
})
}
@imhered 这样不行啊!调用怎么赋值给一个全局变量?
var client = require('./redisdb').accessToken;
console.log(client);//希望这里可以打印出数据
@muzi-xiangxiang 你需要去补补异步方面的知识。 如果想要完全实现同步形式的代码的话,只能用ES7 的Async/Await了(但它实际上也是异步的) 上面给你说的第二种方式 调用的时候应该这样
var client = require('./redisdb').accessToken;
client(function(e,r){
// 这里的 r 就是 accessToken的值
})
@imhered 我知道这样调用,其实我就是不想每次用到accessToken都在回调里面取值
var client = require('./redisdb').accessToken;
var cc;//全局变量
client(function(e,r){
// 这里的 r 就是 accessToken的值
cc=r;//赋值
})
get(cc,function(err,d){//调用是cc不再是undefined
})
@muzi-xiangxiang 如果你强行要同步调用,你可以使用一个包叫deasync,这个包可以把异步变同步,但代价非常大,大到了程序会偶发的hand up
其实楼主只是需要形式上(写法上)的同步而已
因为 redis.get 是一个异步的方法,需要实现同步,则需要阻塞主线程然后等待请求完成。这也就是为什么 deasync 这个包會导致程序 hand up 的原因。
建议楼主可以改下你实现的形式嘛,可以用 async/await 或者 event-emitter
强行同步毕竟与 js 的编程思维相悖啊。。。
强迫症分行。。。
使用sync-request同步了请求连redis都不需要了
var request = require('sync-request');
var res = request('GET', 'https://oapi.dingtalk.com/gettoken');
console.log(res.getBody('utf-8'));
var cc = JSON.parse(res.getBody('utf-8'));
console.log(cc.access_token);
优雅地使用promise
使用bluebird转换,官方都是这么推荐的
bluebird.promisifyAll(redis.RedisClient.prototype);
bluebird.promisifyAll(redis.Multi.prototype);
var value = await client.getAsync(XXXX);
@Yuki-Minakami node8.1.13运行await报错,难道不支持吗?
@muzi-xiangxiang 肯定支持的,看看是不是哪个变量没声明,还有await要跟async一块用
@Yuki-Minakami 都有啊
额,哥们你可能还没用过async/await
async function test(){
var value = await client.getAsync(XXXX);
console.log(value);
}
test()
@Yuki-Minakami 确实没用过…打印Promise { <pending> }不是value的值
test().then(function (d) {
console.log(d);//这样样调用打印d就是value的值
//但这却不是我想要的
})
@muzi-xiangxiang 不好意思刚才打错了,现在再试下楼上的代码 async返回值永远是个promise,直接调用test也拿不到返回值,要调用then才可以
@Yuki-Minakami 谢谢你 其实我就是想把value的值赋给一个全局变量,而不是打印出来但是异步让我无法得到他的值
解决思路,这是一个子进程,父进程把redis数据查询完并写入文件后再启动子线程,子线程同步读取文件获取redis查询的值,整体看来,完成了把异步查询的数据,获取到了子进程的全局变量
来自酷炫的 CNodeMD
client.get('accessToken',function (d,r) {
console.log(r);
return tt=r;
})
//这样tt是永远undefined,因为是异步,程序跑还没有跑完client.get就会跳到console.log,所以tt永远是没有值
console.log(tt);//一直是undefined
另外根据我在公司里的经验,把异步和同步放在一起使用的设计是错误的,这样就会很容易出现你上面的问题,而且非常难debug 如果要想做成像同步,首先把callback函数变成promise,再利用async/await去处理
//这里会用到bluebird
const Bluebird = require('bluebird')
export.clientPromise = new Bluebird( (resolve, reject) => client
.get('accessToken', (d, r) => {
resolve(r)
})
)
然后正如@Yuki-Minakami 所说
async function test(){
var token = await clientPromise()
//然后test你的token。。。。
}
//这里的test()返回值还是promise,async的返回值永远都是promise
test()
其实楼上也说得挺明白的,强行异步变同步 js 的编程思维相悖。
如果你非要同步,可以把accessToken写到json文档里然后用fs.readFileSync(文档地址)
来获取token
要同步换语言,比如openresty。
node短时间内不太可能实现形式同步。