有哪些方式或者方法可以nodejs 回调地狱狱

现在位置:
基于mvc的设计思想,对路由处理做了重构,新建了Dbopt.js即数据库操作对象,设置静态方法,增,删,改,单查,多查,分页查,等等。而不是将数据处理也放到route里面,降低了耦合度。但是问题来了,而问题的根源就是用于高并发的回调函数,至此我才理解了,经常看到的回调地狱到底是什么!
现在我要获取一个集合的文档数量,同时也要获取集合的前10个文档,即分页实现。代码如下
//获取前10个文档
var query=obj.find({}).sort({'date':-1}).skip(0).limit(10);
query.exec(function(err,doc){
callback(err,doc,pageInfo);
//获取当前集合文档数量
obj.find({}).count().exec(function(err,doc){
callback(err,doc);
接下来就发现问题了,就是find()的结果是异步呈现的,也就是说我再外部定义一个变量,在回调函数内部是获取不到查询值的,因为回调函数是异步的,在还没有传递结果之前,我们定义的变量已经被使用(处理过了),即返回值是undefined。看下面代码
obj.find(funciton(err,doc){
console.log(a);//undefined
而且我们也不能像这样返回,
var a=obj.find(funciton(err,doc){
console.log(a);//promise对象
你发现恶心了吧!!!!&所以我们如果想要同时获取数量和结果文档的话,需要嵌套回调函数,即
obj.find(function(err,doc){
obj.count(function(err,nums,doc){
处理数据吧
这样也就明白了,如果需要获取多个查询结果,就要嵌套多个,不仅难看,而且有多个错误处理函数重复,这就是目前我所理解的回调地狱,百度了下,发现了一些解决方案,比如利用async,或者eventProxy,普遍的就是promise解决方案,以前在群里面就听说了promise,好像还有generator,不过现在先研究promise。
什么是promise
Node.js提供的非阻塞IO模型允许我们利用回调函数的方式处理IO操作,但是当需要连续的IO操作时,你的回调函数会多重嵌套,代码很不美观,而且不易维护,而且可能会有许多错误处理的重复代码,也就是所谓的&Pyramid of Doom&。
利用CommonJs的Promise来封装异步函数,使用统一的链式API来摆脱多重回调的噩梦
CommonJs的Promise规范有许多种,我们一般讨论的是Promise/A+规范,它定义了Promise的基本行为。
promise是一个对象,通常代表一个未来异步操作。这个操作可能成功也可能失败,它有三种状态Pending,Fulfilled,Rejected,反别代表未完成、已完成、失败。一旦Promise对象的状态从Pending变成Fulfilled或者Rejected任意一个,它的状态都没有办法再被改变。
核心方法,then(),这个方法去操作未来可能成功后返回的值或者是失败的原因。这个then方法是这样子的:
promise.then(onFulfilled, onRejected)
//该方法接收两个参数,通常是两个函数,一个用来处理成功后的结果,一个用来处理失败后的原因
**如果传递给它的不是一个函数,这个参数将会被忽略**
//同时该方法返回的还是promise对象,这个给了我们实现像jquery链式调用的可能。
下面我们来研究下这两个参数,首先浮现在我脑海中的是成功函数应该接受一个参数doc表示成功结果,失败函数接受一个err表示错误原因,用于错误处理。
两个函数能返回值,如果返回的是promise对象,整体then方法返回的就是一个promise对象,如果不是promise对象,该值是下一个then方法的成功函数的第一个参数,但是如果没有对应的成功失败函数,则返回的是上一个promise的返回值。 如果有异常抛出,还是会返回promise对象,只不过在下一个then方法中会将Error传递给失败函数的第一个参数。
好吧看的我是云里雾里的。觉得还是代码来的实在。 但是这个promise仅仅是个规范,下面就是规范的实现q库,之前也听说过,现在终于要揭开它神秘的面纱了。
规范的实现,q 库
q是一个对Promise/A+有着较好实现规范的库。 首先我们需要创建一个Promise对象,关于Promise对象创建的规范在Promise/B中,这里不做详细的解释,直接上代码 这是人家的,对于B,好吧,我还是小白
function(flag){
var defer = q.defer();
fs.readFile(&a.txt&, function(err, data){
if(err) defer.reject(err);
else defer.resolve(data);
return defer.
多数Promise的实现在Promise的创建上大同小异,通过创建一个具有promise属性的defer对象,如果成功获取到值则调用defer.resolve(value),如果失败,则调用defer.reject(reason),最后返回defer的promise属性即可。这个过程可以理解为调用defer.resolve将Promise的状态变成Fulfilled,调用defer.reject将Promise的状态变成Rejected。
在面对一系列连续的异步方法时,怎么利用Promise写出漂亮的代码呢?看下下面的例子
promise0.then(function(result){
// dosomething
}).then(function(result) {
// dosomething
return promise1;
}).then(function(result) {
// dosomething
}).catch(function(ex) {
console.log(ex);
}).finally(function(){
console.log(&final&);
在上面的代码中,then方法只接受OnFulfilled,而catch方法实际上就是then(null, OnRejected),这样的话只要一系列异步方法只要始终是成功返回值的,那么代码就会瀑布式的向下运行,如果其中任意一个异步方法失败或者发生异常,那么根据CommonJs的Promise规范,将执行catch中的function。q还提供了finally方法,从字面上也很好理解,就是不论resolve还是reject,最终都会执行finally中的function
看上去似乎不错,代码更以维护且美观了,那么如果希望并发呢?
q.all([promise0, promise1, promise2]).spread(function(val0, val1, val2){
console.log(arguments);
).then(function(){
console.log(&done&);
}).catch(function(err){
console.log(err);
也为并发提供了api,调用all方法并传递一个Promise数组即可继续使用then的链式风格。还有像q.nfbind等可以将Node.js的原生API转化成Promise来统一代码格式也是挺好的。更多api在这里就不一一详述了
好吧,这个是网上的教程,看完了,大致对promise有了清楚的认识,promise主要是处理nodejs控制流的问题。确实es6也实现了原生的promise,明天再好好研究,并应用到程序中。
(R)演示站(TM) | 版权所有 | 若非注明 | 均为原创(TM)
㊣ 转载请附上文章链接并注明:
㊣ 本文永久链接:下次自动登录
现在的位置:
& 综合 & 正文
ios 回调常用的几种方式总结
1.函数指针--最本质,最底层的调用
2.块语法--包,本质是通过函数指针调用的
3.target-action模式-在函数指针之上的封装(借助OC函数名字符串通过SEL-@selector来查找函数指针),不知道要回调的函数(本质上是函数指针)
4.委托协议模式--在函数指针之上的封装(借助OC函数名字符串通过SEL-@selector来查找函数指针),知道要回调的函数 (本质上是函数指针)
5.消息通知--用单个对象给多个对象发消息(本质上还是函数指针)
&&&&推荐文章:
【上篇】【下篇】Android后台强制结束进程,Application入口或者activity回调的是哪个方法?
回复讨论(解决方案)
如果是系统强制结束,不会调用的
找到了,,是这个方法
public&void&onTerminate(){
super.onTerminate();
System.out.println(&quot
10:44&&&[]
比如EnumWindows,是不是就是EnumWindows所在的线程?
那么一个全局钩子,它的钩子回调函数的调用的线程是哪个啊
回复讨论(解决方案)
EnumWindows:
The&EnumWindows&function&nbsp
-13:47&&&[]
回调函数和主函数之间隔着的这个OS,我对这点的逻辑关系不是很清晰。
2)我想在调试vc程序时,看看试验程序在运行期间,有哪些进程启动和终止,请问有什么好办法吗或者是专门看的软件?
回复讨论(解决方案)
首先,消息循环,中的消息不是OS回调的,代码中也能看出来,是你主动用GetMessage
-18:36&&&[]
),并且在执行完毕后回调到onPostExecute(),我们可以在onPostExecute下面获得异步任务的结果,并使结果安全地在UI线程中显示。AsyncTask是个抽象类,这些回调方法可能是抽象方法,也可能是普通的方法,像doInBackground是抽象方法,强制使用AsyncTask的
18:22&&&[]
请问如何强制结束一个进程?进程名为“ght.exe”,是恶意软件,有许多个这样的进程,在不更改文件属性、注册表、系统设置等情况下如何全部结束?(注:是强制结束)请在编程时不要添加控件,运行程序它会自己进行,不需要人工干预。
回复讨论(解决方案)
unit&Unit1;&nbsp
21:04&&&[]
我的问题是,在系统几乎死机的时候,如果让自己的程序还能获取CPU分配的时间,将我需要结束的进程结束掉?谢谢
普通方法都试了,不行,因为多线程死机的时候,几乎没有程序可以响应了。
回复讨论(解决方案)
一个偏方:在你的程序中启动一个console窗口,然后执行调试去,如果出现
02:09&&&[]
,onResume--&Activity_A的onStop,期间会看到Activity的onSaveInstanceState(),OnRestoreInstanceState(),OnRestart()方法的回调源码)
需要了解的几点概念和知识点:
Instrumentation是执行
20:45&&&[]
使用android自动化测试工具monkeyrunner启动应用时,需要填写被测程序的包名和启动的Activity,以下有两种查看应用包名package和入口activity名称的方法:方法一:使用aapt & &//aapt是sdk自带的一个工具,在sdk
14:56&&&[]
activity再可见的时候,imageView1 显示的内容为空........................,但不会抛异常 2.activity死前的回调方法 2.11用户按后退键的时候触发的方法有=》onBackPressed,onPause,onStop,onDestroy 2.12 用户
11:31&&&[]
个人喜欢复杂东西简单化,这里就不做理论性描述,实现这方法当然很多,比如可以使用广播,实现Activity回调再调用Fragment等,这里是直接Activity回调到Fragment
效果流程图
2.实现流程 &2.1 接口类,如CallBackInterface.java
07:58&&&[]
看到标题你可能会想是一个多么高大上的技巧呢?其实很一般就是自定义回调函数. 首先我们知道activity之间的数据传递有几种方式: 一是startActivityForResut()启动一个activity,当栈顶activity 调用onActivityResult()并且 finish 掉时
04:20&&&[]
...0...1...2...3...4...5...6...7...8...9
卧槽,哪个傻逼写的博文,侮辱我的智商不是吗,嘻嘻,是为了做比较,接下来看看利用回调, ClassA 是怎么调用 ClassB中的 方法的,注意是回调:
让ClassB 实现 ClassA定义的接口
11:30&&&[]

我要回帖

更多关于 什么是回调地狱 的文章

 

随机推荐