node c回调函数实际使用场景怎么看

&&&&Node.js是很好,异步回调模式返回值让我头疼不已啊,今日还是写下今天学习的成果,起由是因为在使用mongoose查询的时候,多个查询相互依赖会层层嵌套,看起来N不爽,我们可以使用并行查询完毕然后,返回想要的结果即可,代码看起来会美观很多,例如:
User.findOne({userid:userid},function(err,findUser){
&&&&Group.find({userid:findUser.userid},function(err,group){
&&&&&&&&GroupQZ.find(groupid:group.groupid}.function(err,qz){}
以上可以使用eventproxy来并行处理。在一个函数里把三个返回的参数合并成一个json返回。
看我设计的就是死活得不到想要的值,懂的一看便知道怎么回事
module.exports.findUser&=&function(condition){
&&&&User.findOne(condition,function(err,findUser){
&&&&&&&&userinfo&=&findU
&&&&return&//返回的结果始终是undefined
javascript是按照顺序解析的,到查询的时候是异步执行还没有赋值就直接返回了。
我想要的理想设计方法
module.exports.findUser=&function(condition)
&&&&return&//意思些一个通用函数,传回条件直接返回想要的结果
查了很久还是找到很多解决办法,比如这篇文章,讲述node.js的promise库对如何取得异步回调函数,加载模块依赖等等。
解决办法:
&&&&&&&&&&&&
promise解决方案排名:
原来mongoose自带的promise也可以解决:
//Utility&function&(put&it&in&a&better&place)
&&var&saveInPromise&=&function&(model)&{
&&&&var&promise&=&new&mongoose.Promise();
&&&&model.save(function&(err,&result)&{
&&&&&&promise.resolve(err,&result);
&&&&return&
Then you can use it instead of save to chain your promises
&&var&User&=&mongoose.model('User');
&&var&Channel&=&mongoose.model('Channel');
&&var&Article&=&mongoose.model('Article');
&&//Step&1
&&var&user&=&new&User({data:&'value'});
&&saveInPromise(user).then(function&()&{
&&&&//Step&2
&&&&var&channel&=&new&Channel({user:&user.id})
&&&&return&saveInPromise(channel);
&&}).then(function&(channel)&{
&&&&//Step&3
&&&&var&article&=&new&Article({channel:&channel.id})
&&&&return&saveInPromise(article);
&&},&function&(err)&{
&&&&//A&single&place&to&handle&your&errors
& 著作权归作者所有
人打赏支持
码字总数 26950
前端工程师
引用来自“Themores”的评论 save 是同步的吗不然看着有问题啊。这个代码。。。save(function(err,doc){ //dosomesthing})是异步的//Utility function (put it in a better place)
var saveInPromise = function (model) {
var promise = new mongoose.Promise();
model.save(function (err, result) {
promise.resolve(err, result);
}这个返回的是promise对象,promise其实也是异步的,只不过用他的好处是少写很多回调。
save 是同步的吗不然看着有问题啊。这个代码。。。save(function(err,doc){ //dosomesthing})
多谢,救了命了,英文死活搜不到
学习了,今天回去试试
评论删除后,数据将无法恢复
这次的示例基于之前的LoginDemo(见使用cookie保持登录),我们引入MongoDB来保存用户数据。要运行这个示例,前提是MongoDB数据要正常运行(见Node.js开发入门——MongoDB与Mongoose)。示例...
初始JavaScript Promises之二 上一篇我们初步学习了JavaScript Promises,本篇将介绍Promise如何优雅地进行错误处理以及提升操作node.js风格1的异步方法的逼格,没错就是使用promisify2。 异...
所谓全端指的是前后端采用同一个平台进行开发,mean是一种全端开发解决方案,mean包括MongoDB、Express、Nodejs及angularjs。 mongodb是nosql数据库; nodejs是一个平台,用于支持在浏览器之...
nevermore1981
nodejs是比较简单的,只有你有前端js基础,那就按照我的办法来吧!一周足矣 推荐技术栈 express 4.x (express最新版本,初学者先别去碰koa) mongoose(mongodb) bluebird(Promise/A+实现...
  学习和使用Node.js已经有两个月,使用express结合mongoose写了一个web应用和一套RESTful web api,回过头来看Node.js官网首页对Node.js的介绍:Node.js uses an event-driven, non-block...
Express + Mongoose 极简入门 今天尝试使用express + mongoose,构建了一个简单的Hello world,实现以下功能: 定义mongodb使用的Schema,一个User 访问/输出Hello world 访问/init向mongodb...
笔者在之前的一片博客中简单的讨论了Python和Javascript的异同,其实作为一种编程语言Javascript的异步编程是一个非常值得讨论的有趣话题。 JavaScript 异步编程简介 回调函数和异步执行 所谓...
——基于es6:Promise/A+ 规范简单实现 异步流程控制思想 前言:   nodejs强大的异步处理能力使得它在服务器端大放异彩,基于它的应用不断的增加,但是异步随之带来的嵌套、难以理解的代码...
grootzhang
当你还在为开发Nodejs使用哪种数据库而犹豫时,那就选择mongodb吧。在nodejs中操作mongodb非常方便,mongodb天然的支持JSON,增删改查都非常简单。本篇博客主要来实现在nodejs中使用mongodb...
chenyufeng1991
Node.js下基于Express + Socket.io 搭建一个基本的在线聊天室 一、聊天室简单介绍   采用nodeJS设计,基于express框架,使用WebSocket编程之 socket.io机制。聊天室增加了 注册登录 模块 ...
没有更多内容
加载失败,请刷新页面
好久没有真正的在纸质笔记本上写过东西了,感觉都快不会写字了,笔画都不知道怎么写了。接下来就说说咱们的正事。 日,我做了一个决定,那就是去参加安全培训(可能是我职业生涯中...
关于工作中的人际交往 Intro 写了篇发泄情绪的博客,但不会发布出来。 大概就是,要么忍,要么滚。 以及一些不那么符合社会主义核心价值观,不满于大资本家与小资本家剥削的废话。
1.用户发送请求至前端控制器DispatcherServlet 2.DispatcherServlet收到请求调用HandlerMapping处理器映射器。 3.处理器映射器根据请求url找到具体的处理器,生成处理器对象及处理器拦截器(...
JavaSon712
博主前面文章有介绍过软件的安装,可以帮助IT人员顺利的完成功能软件安装;但是,对于我们运维人员或者需要管理软件安装的项目经理来说,有些应用一次行需要搭建很多台相同的软件环境(如tom...
整合步骤 1. Oracle驱动引入 Oracle驱动一般不能通过maven仓库直接下载得到,需自行下载并导入到项目的lib目录下,建议通过如下pom依赖引入下载的Oracle驱动
&!-- Oracle 驱动 --&...
下面创建一个并行流,与顺序流 //顺序流Stream.iterate(0L, i -& i + 1)
.limit(Integer.MAX_VALUE)
.reduce(0L, Long::sum);//并行流Stream.iterate(0L, i -& i......
二分法采用向下取整的方法 使用有序数组的好处是查找的速度比无序数组快的多,不好的方面是因为要将所有靠后的数据移开,所以速度较慢,有序数组和无序数组的删除操作都很慢。 有序数组在查找...
沉迷于编程的小菜菜
前言 上几节讲了利用Mybatis-Plus这个第三方的ORM框架进行数据库访问,在实际工作中,在存储一些非结构化或者缓存一些临时数据及热点数据时,一般上都会用上mongodb和redis进行这方面的需求。...
一、前言 现实中,大部分数据都是无标签的,人和动物多数情况下都是通过无监督学习获取概念,故而无监督学习拥有广阔的业务场景。举几个场景:网络流量是正常流量还是攻击流量、视频中的人的...
A--&B A在发送请求之前,用乐观锁,减少对B的重复调用,这样一定程度上是幂等性。 比如A系统支付功能,要调用B系统进行支付操作,但是前端对"支付"按钮不进行控制,即用户会不断多次点击支付...
汉斯-冯-拉特
没有更多内容
加载失败,请刷新页面
文章删除后无法恢复,确定取消删除此文章吗?
亲,自荐的博客将通过私信方式通知管理员,优秀的博客文章审核通过后将在博客推荐列表中显示
确定推荐此文章吗?
确定推荐此博主吗?
聚合全网技术文章,根据你的阅读喜好进行个性推荐
指定官方社区
深圳市奥思网络科技有限公司版权所有Pages: 1/2
主题 : 浅析回调函数和schedule
级别: 圣骑士
UID: 298324
可可豆: 800 CB
威望: 798 点
在线时间: 282(时)
发自: Web Page
来源于&&分类
浅析回调函数和schedule&&&
本帖被 偶尔e网事 执行加亮操作()
Cocos2d-x中涉及到不少的回调函数,有时候我们在用的过程中并没有留意,但如果你仔细推敲一下,发现这里边的故事还真不少,好久没有跟新博客,这篇博客作为一个开头吧,我们借助菜单回调和schedule回调来说下3.0中的回调函数的一些应用。1、回调的第一种方法,传统方法,传入target和回调函数,在适当的时候用target调用回调函数。以下的函数调用是2.x创建菜单项使用回调函数的方法,第三个参数是target,第四个参数需要传入一个函数指针,这个函数指针的定义是:typedef void (Ref::*SEL_MenuHandler)(Ref*);传入的第三第四个参数的作用就是当需要回调函数的时候用target来调用你传入的这个函数,所以这个函数一定是target的成员变量。
auto menu1 = MenuItemImage::create(&CloseNormal.png&, &CloseSelected.png&, this, menu_selector(HelloWorld::closeCallback));
2、回调的第二种方法,使用std::bindCC_CALLBACK_1的定义std::bind(&__selector__,__target__, std::placeholders::_1, ##__VA_ARGS__) bind其实就是传入一个函数,产生一个新的函数,第一个就是一个函数地址,如果这个函数是类的成员函数,我们需要第二个参数,告诉调用哪个对象的这个函数,第三个参数是一个占位符,CC_CALLBACK_0,CC_CALLBACK_1 ...的不同点就在这里,后边的数字代表的就是bind的占位符数量,引擎对他们进行了不同的宏定义,可以跟进查看,后边的##__VA_ARGS__可以传入多个参数
auto menu2 = MenuItemImage::create(&CloseNormal.png&, &CloseSelected.png&, CC_CALLBACK_1(HelloWorld::closeCallback, this));
下面不使用cocos2d-x的callback宏,我们来直接使用bind
auto menu3 = MenuItemImage::create(&CloseNormal.png&,&CloseSelected.png&,std::bind(&HelloWorld::callback,this,std::placeholders::_1,1,false));
这里是callback的定义void HelloWorld::callback(cocos2d::Ref * ref,int i,bool b),我们使用bind绑定了这个函数,将它的第一个参数使用占位符保留了下来,而第二个和第三个参数分别提供了值,这个时候通过bind就产生了一个新的函数callback(cocos2d::Ref * ref)。系统在回调的时候会传入一个ref的参数,而i和b就是我们在bind中提供的值。最后我们来看一下menu3的create的第三个参数ccMenuCallback,它的定义如下:typedef std::function&void(Ref*)& ccMenuC这个东西就是std::function,尖括号中的内容就是告诉你它需要的函数返回值是void,而需要的参数是Ref *,也就是说它需要的是返回值是void,参数是Ref *的函数,所以std::function其实就是一种类型,就像普通的数据类型那样的类型,一种用来说明函数类型的类型,最后的最后我们知道通过std::bind绑定的函数需要使用std::function类型去接受。3、回调的第三种方法:使用lambda表达式将lambda表达式直接写在参数中
auto menu4 = MenuItemImage::create(&CloseNormal.png&,&CloseSelected.png&,
[](Ref * ref){
log(&close&);
如果要使表达式能够访问外部变量,可以在[]内写入“&”或者“=”加上变量名,其中“&”表示按引用访问,“=”表示按值访问,变量之间用逗号分隔。
auto closeMenu1 = MenuItemImage::create(&CloseNormal.png&,&CloseSelected.png&,
                                            [this,&size](Ref * ref){
                                    auto sprite = Sprite::create(&HelloWorld.png&);
                                                sprite-&setAnchorPoint(Point(0,0));
                                    this-&addChild(sprite);
                                            });
为了说明lambda的类型,这次将lambda写到参数列表的外边。
std::function&void(Ref *)& call = [](Ref * ref)
auto closeMenu2 = MenuItemImage::create(&&,&&,call);
更多的时候为了省事,我们都将std::function的那一长串东西用一个auto代替。通过上面的例子就说明了lambda返回的类型也是需要std::function接收的,通过上面的例子我们得出这样的结论,如果要回调某一个函数,就像菜单的回调,按钮的回调,schedule的回调,CCallFunc动作序列,我们可以传入函数指针+调用对象target,或者使用std::function,而std::function可以通过std::bind绑定获得,或者通过lambda表达式获得。接下来看一下回调函数在schedule中是如何应用的。
this-&schedule(SEL_SCHEDULE(&HelloWorld::call), 1.0f);
this-&schedule(schedule_selector(HelloWorld::call), 1.0f);
以下的俩种调用方式道理都是一样的,仔细比较一下发现使用SEL_SCHEDULE需要加一个取地址符,使用schedule_selector不需要,原因看下各自的定义大家就明白了。SEL_SCHEDULE直接就是函数指针,而schedule_selector是个宏定义,传入里边的参数,用static_cast转化为SEL_SCHEDULE类型的时候加上了取地址符。这里把这个基础的问题说下,也是对c++的一种复习吧!
typedef void (Ref::*SEL_SCHEDULE)(float);
#define schedule_selector(_SELECTOR) static_cast&cocos2d::SEL_SCHEDULE&(&_SELECTOR)
我们发现一个问题,用这种方法做回调的时候,不是需要传入一个target吗,为什么这种方法没有传入这个target,或者说是this参数,我们只好翻翻源码了,那就一步步跟进源码,跟到这里(代码在下边)的时候发现了用变量_schedule调用了一个schedule函数,这个_schedule是什么,我们在文件中查找一下,发现_scheduler = director-&getScheduler();原来它是通过Director获得的,其实它的类型是Scheduler,这个东西是一个单例,在Director类中保持着对这个单利对象的引用。同时这个schedule函数的第二个参数就是this,而这个this就是我们要得target,所以这就说明这个target不是没有传入,而是在引擎的内部传入了this!
void Node::schedule(SEL_SCHEDULE selector, float interval, unsigned int repeat, float delay)
    CCASSERT( selector, &Argument must be non-nil&);
    CCASSERT( interval &=0, &Argument must be positive&);
    _scheduler-&schedule(selector, this, interval , repeat, delay, !_running);
我们继续跟进schedule函数,发现文件跳到了Scheduler类中,调用了Scheduler类的schedule,到这里所有的东西就明白了。我们在类中调用schedule,表面上调用的是Node类的schedule,其实最后调用的是Scheduler类中得schedule函数。我们所说的第一种形式的回调this的传入是在node类中转调用scheduler中的schedule的时候帮我们传入了this。最后有必要看一下这个schedule的声明。
void Scheduler::schedule(SEL_SCHEDULE selector, Ref *target, float interval, unsigned int repeat, float delay, bool paused)
那我们想要的第二种回调的形式呢?我找了Node的整个schedule函数都没有发现,因为Node最终还是调用的scheduler类的函数,所以我们去scheduler类中找一找,果然,我发现了采用第二种回调形式的schedule函数,声明如下。
void Scheduler::schedule(const ccSchedulerFunc& callback, void *target, float interval, unsigned int repeat, float delay, bool paused, const std::string& key)
我们跟进去看一下ccSchedulerFunc的定义,如下:
typedef std::function&void(float)& ccSchedulerF
怎么样,一个std::function出来了吧,但是Node中却没有提供给我们这样的schedule函数调用,有如此简单的调用形式却不用岂不是可惜?那我们要怎么办?很简单,直接使用Scheduler中得函数不就可以了。所以采用第二种回调方式的调用方法如下。
auto _schedule = Director::getInstance()-&getScheduler();
    _schedule-&schedule([](float tm){log(&%f&,tm);}, this, 1.0f,!this-&isRunning(),&xiaota&);
现在,我们可以尽情的使用lambda表达式了,省去了麻烦的函数头文件声明,这几个参数很简单是类似于普通的schedule函数,只是最后一个参数要注意一下,他是一个string类型,这个string类型有什么作用呢?我们让schedule跑了起来,停的时候该怎么办呢?对,就是用的这个string,当然还有第二个参数target,所以这里你传入的这个key值必须和其他的key值保持不同,否则的话停掉的时候就出错了。这个原因估计也是引擎组没有将这个接口放到Node中得因素吧!现在schedule的用法和小小的分析就到这里结束了,大家如果发现有什么错误之处还请指正![ 此帖被小塔在 12:50重新编辑 ]
欢迎访问cocos2d-x博客www.zaojiahua.com皂荚花。
级别: 版主
UID: 300874
发帖: 2378
可可豆: 3131 CB
威望: 3189 点
在线时间: 1378(时)
发自: Web Page
赞!很细致的分析。很多人在纠结Schedule不能用lambda。其实也是可以的。只是用起来相对麻烦点。如果知道了这整个调用原理,想刚给Schedule或者menucallback传参对引擎进行适当的修改也是可以的。
级别: 新手上路
可可豆: 90 CB
威望: 70 点
在线时间: 96(时)
发自: Web Page
受教了,感谢LZ分享
级别: 骑士
UID: 231183
可可豆: 2097 CB
威望: 1384 点
在线时间: 295(时)
发自: Web Page
级别: 骑士
UID: 295073
可可豆: 2833 CB
威望: 1703 点
在线时间: 444(时)
发自: Web Page
mark,学习
我的站点:http://qianuuu.com/
级别: 新手上路
可可豆: 82 CB
威望: 72 点
在线时间: 72(时)
发自: Web Page
太详细了,顿时让我茅塞顿开啊,哈哈哈。。。。。。。。。。
勇敢的做好一名开发者
级别: 新手上路
可可豆: 6 CB
威望: 6 点
在线时间: 9(时)
发自: Web Page
菊花突然开了。好爽
级别: 圣骑士
UID: 234523
可可豆: 2339 CB
威望: 1570 点
在线时间: 445(时)
发自: Web Page
回 楼主(小塔) 的帖子
很详细的教程,分析很到位,辛苦楼主了!
没有最好,只有更好!
可可豆: * CB
威望: * 点
在线时间: (时)
注册时间: *
最后登录: *
发自: Web Page
级别: 新手上路
UID: 327376
可可豆: 42 CB
威望: 27 点
在线时间: 9(时)
发自: Web Page
熬夜狗路过,顺便留爪
Pages: 1/2
关注本帖(如果有新回复会站内信通知您)
发帖、回帖都会得到可观的积分奖励。
按"Ctrl+Enter"直接提交
关注CocoaChina
关注微信 每日推荐
扫一扫 关注CVP公众号
扫一扫 浏览移动版关于Node.js的回调函数
Node.Js异步编程的直接表现方式就是回调。异步编程依托于回调来实现,但不能说使用了回调后程序就异步化了。回调函数在完成任务后就会被调用,Node使用了大量的回调函数,node所有api都支持回调函数。比如,我们在操作文件的时候,可以一边读取文件,一边执行其他的命令,在读取文件完成后,我们将文件内容作为回调函数的参数返回,这样在执行代码时就没有阻塞或等待文件I/O操作,这就大大提高了Node.js的性能,可以处理大量的并发请求。一个例子有一个叫做test.txt的文件,内容如下:Hello&my&callback&world阻塞代码创建一个读取文件的readfile.js文件,代码如下:&执行非阻塞代码代码执行总结通过上面的两个阻塞和非阻塞的例子,第一个例子文件读取完成后才会执行下面的代码,第二个我们不需要等待文件读取完成,就可以执行下面的操作。阻塞是同步的,非阻塞时异步的。异步完成后,可以在回调中,进行后续的操作。
随时随地看视频nodejs回调函数和返回值 - CNode技术社区
这家伙很懒,什么个性签名都没有留下。
现在我需要用Nodejs抓取一个网站上面的数据,数据可能有几千条,分几十页,而且每一页都是一次请求,现在我需要对外部提供一个接口,就是可以一次返回这几千条数据的接口。
问题是是获取页数之后循环请求,但是返回的数据在每次请求的回调函数里,我该怎么把这些回调函数里面的数据汇总到一起并返回给调用接口啊?
用 eventproxy
使用计数器.
你要分发多少个处理函数,就要对每一个完成的回调函数进行计数判断:
function check () {
if (nums === 0) { // do something. }
每一个回调函数中都使用这个检测函数来进行逻辑监测,以回到下一个进程线
类似于交换机侦听
…(…, function (…) {
比如我写的howdo吧,虽然简单,也是可以完成的
var howdow = new Howdo();
// 这是页数,可以顺序也可以是乱序
var pages = [0, 1, 2, 3, 4, ...];
pages.forEach(function(page) {
// 分配任务
howdo.task(function(done) {
request(page, function(e, result) {
// 各种处理之后...,提交任务
done(e, result);
// 分页去查询,这些任务之间没有依赖关系
// 各个任务可以一起做
howdo.together(function(e, page0, page1, page2, page3, page4, ...) {
// 只要其中1个任务出现错误,都会返回错误
if(e) return callback(e);
// 参数顺序和分配任务时的顺序一致
// 这里得到了所有的分页数据
// 然后再拼接返回即可
var data = [].concat.apply([], [].slice.call(arguments, 1));
callback(null, data);
你可以看一下 async 模块的 map方法
CNode 社区为国内最专业的 Node.js 开源技术社区,致力于 Node.js 的技术研究。
服务器赞助商为
,存储赞助商为
,由提供应用性能服务。
新手搭建 Node.js 服务器,推荐使用无需备案的nodejs 一个函数的临时变量 被用于 另一个回调函数中.....
真不熟悉这个语法,求解
[问题点数:50分,结帖人ljxh401]
本版专家分:0
结帖率 83.33%
CSDN今日推荐
本版专家分:122560
2017年 总版技术专家分年内排行榜第七
2018年5月 Web 开发大版内专家分月排行榜第一2018年1月 Web 开发大版内专家分月排行榜第一2017年12月 Web 开发大版内专家分月排行榜第一2017年6月 Web 开发大版内专家分月排行榜第一2017年2月 Web 开发大版内专家分月排行榜第一2016年3月 Web 开发大版内专家分月排行榜第一2015年8月 Web 开发大版内专家分月排行榜第一
2018年6月 Web 开发大版内专家分月排行榜第二2018年4月 Web 开发大版内专家分月排行榜第二2018年3月 Web 开发大版内专家分月排行榜第二2018年2月 Web 开发大版内专家分月排行榜第二2017年11月 Web 开发大版内专家分月排行榜第二2017年10月 Web 开发大版内专家分月排行榜第二2017年9月 Web 开发大版内专家分月排行榜第二2017年8月 Web 开发大版内专家分月排行榜第二2017年7月 Web 开发大版内专家分月排行榜第二2017年5月 Web 开发大版内专家分月排行榜第二2017年4月 Web 开发大版内专家分月排行榜第二2017年3月 Web 开发大版内专家分月排行榜第二2017年1月 Web 开发大版内专家分月排行榜第二2016年11月 Web 开发大版内专家分月排行榜第二2016年9月 Web 开发大版内专家分月排行榜第二2016年8月 Web 开发大版内专家分月排行榜第二2016年7月 Web 开发大版内专家分月排行榜第二2016年6月 Web 开发大版内专家分月排行榜第二2016年5月 Web 开发大版内专家分月排行榜第二2016年4月 Web 开发大版内专家分月排行榜第二2016年2月 Web 开发大版内专家分月排行榜第二2015年9月 Web 开发大版内专家分月排行榜第二2015年7月 Web 开发大版内专家分月排行榜第二2015年6月 Web 开发大版内专家分月排行榜第二2015年4月 Web 开发大版内专家分月排行榜第二2015年3月 Web 开发大版内专家分月排行榜第二2015年2月 Web 开发大版内专家分月排行榜第二
2016年12月 Web 开发大版内专家分月排行榜第三2016年10月 Web 开发大版内专家分月排行榜第三2016年1月 Web 开发大版内专家分月排行榜第三2015年12月 Web 开发大版内专家分月排行榜第三2015年11月 Web 开发大版内专家分月排行榜第三2015年10月 Web 开发大版内专家分月排行榜第三2015年5月 Web 开发大版内专家分月排行榜第三2015年1月 Web 开发大版内专家分月排行榜第三2014年12月 Web 开发大版内专家分月排行榜第三
本版专家分:0
匿名用户不能发表回复!|
其他相关推荐}

我要回帖

更多关于 c回调函数实际使用场景 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信