nodejs promise for q.js
2016-11-06 23:08
309 查看
摘要: q.js在nodejs里是一个非常流行的promise库,支持浏览器端使用,详情请点击这里
q.js跟async要解决的问题差不多,都是解决回调函数的嵌套问题,避免嵌套层级太深导致一系列的问题.只是q.js是以promise来实现回调的扁平化,而async则是通过流程来控制多个异步回调的处理.
q.js在nodejs里是一个非常流行的promise库,支持浏览器端使用,详情请点击这里
q.js跟async要解决的问题差不多,都是解决回调函数的嵌套问题,避免嵌套层级太深导致一系列的问题.只是q.js是以promise来实现回调的扁平化,而async则是通过流程来控制多个异步回调的处理.
q.js的所有方法操作的对象都得是一个promise对象,下面来说说怎么用q来创建promise对象
下面所有实例统一在nodejs环境里执行,请执行下面命令安装q.js,然后引用它
下面会用到文件模块,所以也要引用
说完了创建promise对象,然后我们来看看怎么使用这些对象吧
上面的q.all方法成功返回的结果会返回一个包含所有异步方法结果的数组,出现一个异步方法异常则执行错误回调方法.
注意q.all 里的promise数组支持不带延迟对象以及延迟对象
q.when 使用此方法执行不带延迟对象以及延迟对象promise,不支持传递数组内带延迟对象
返回的结果处理跟q.all一样
注意q.when 不支持数组内传递延迟对象
其实nfcall = node function call, nfapply = node function apply,传递的传递参考call与apply方法,回调处理跟上面的一样
当回调函数内出现异常时,回调异常函数是catch不到的,这里q提供了一个fail方法
以上都是单一的异步方法调用,下面说说q里的链式调用
所谓的链式调用就是在成功回调内返回一个新的promise对象,假如之后的回调不需要获取闭包内容的话,可以直接返回,否则可以接着写then方法调用
总结
q.js是一个非常好用的promise实现,前后端都可以用,像ng里就有一个$q的实现,强烈推荐大家使用这个.
q.js跟async要解决的问题差不多,都是解决回调函数的嵌套问题,避免嵌套层级太深导致一系列的问题.只是q.js是以promise来实现回调的扁平化,而async则是通过流程来控制多个异步回调的处理.
q.js在nodejs里是一个非常流行的promise库,支持浏览器端使用,详情请点击这里
q.js跟async要解决的问题差不多,都是解决回调函数的嵌套问题,避免嵌套层级太深导致一系列的问题.只是q.js是以promise来实现回调的扁平化,而async则是通过流程来控制多个异步回调的处理.
q.js的所有方法操作的对象都得是一个promise对象,下面来说说怎么用q来创建promise对象
下面所有实例统一在nodejs环境里执行,请执行下面命令安装q.js,然后引用它
npm install q --save var q = require('q'), fs = require('fs');
下面会用到文件模块,所以也要引用
创建promise对象
q.fcall 传递给此方法一个返回值的函数或者一个defer实例,将会创建一个promise对象
var promise = q.fcall(function(){ return [10, 20]; }); var promise1 = q.fcall(function(){ var deferred = q.defer(); fs.readFile('../data/file2.txt', 'utf8', deferred.makeNodeResolver()); return deferred.promise; });
q.defer 通过延迟对象来创建promise对象
var getFile = function(){ var deferred = q.defer(); fs.readFile('../data/file.txt', 'utf8', function(err, content){ if(err){ deferred.reject(new Error(err)); }else{ deferred.resolve(content); } }); return deferred.promise; }
q.promise 传递此方法一个函数来创建promise对象
var getFilePromise = function(){ return q.promise(function(resolve, reject, notify){ fs.readFile('../data/file.txt', 'utf8', function(err, content){ if(err){ reject(new Error(err)); }else{ resolve(content); } }); }) }
说完了创建promise对象,然后我们来看看怎么使用这些对象吧
使用promise对象
最简单的使用方法就是直接使用then方法,传入一个成功回调与一个异常回调// fcall创建的promise promise.then(function(msg){ console.log(msg); }, function(err){ // do stuff }); // q.defer创建的promise getFile().then(function(msg){ console.log(msg); }, function(err){ // do stuff }) // q.promise创建的promise中q.defer使用一样 q.all 使用此方法可以保证执行多个异步方法之后执行回调 q.all([promise, promise1]).then(function(msg){ console.log('normal', msg); }, function(err){ console.log(err); })
上面的q.all方法成功返回的结果会返回一个包含所有异步方法结果的数组,出现一个异步方法异常则执行错误回调方法.
注意q.all 里的promise数组支持不带延迟对象以及延迟对象
q.when 使用此方法执行不带延迟对象以及延迟对象promise,不支持传递数组内带延迟对象
q.when(promise1, function(msg){ log('when' + msg); },function(err){ console.log(err); })
q.when(promise, function(msg){ log('when' + msg); },function(err){ console.log(err); }) q.when([promise, promise], function(msg){ log('when' + msg); },function(err){ console.log(err); })
返回的结果处理跟q.all一样
注意q.when 不支持数组内传递延迟对象
q.nfcall | q.nfapply 这两方法是对nodejs里异步方法的适配,不用写上面promise对象定义里的resolve及reject等
q.nfcall(fs.readFile, '../data/file.txt', 'utf8').then(function(msg){ console.log('nfcall', msg); }) q.nfapply(fs.readFile, ['../data/file.txt', 'utf8']).then(function(msg){ console.log('nfapply', msg); })
其实nfcall = node function call, nfapply = node function apply,传递的传递参考call与apply方法,回调处理跟上面的一样
当回调函数内出现异常时,回调异常函数是catch不到的,这里q提供了一个fail方法
var getFileHandy = function(){ var deferred = q.defer(); fs.readFile('../data/file1.txt', 'utf8', deferred.makeNodeResolver()); return deferred.promise; } getFileHandy().then(function(msg){ console.log(msg); throw new Error('demo exception'); }).fail(function(err){ // 此处可以catch 所有的异常 console.log(err); });
以上都是单一的异步方法调用,下面说说q里的链式调用
promise1.then(function(msg){ return getFile(); }). then(function(msg){ return getFileHandy() .then(function(data){ return getFilePromise(); }) .then(function(content){ console.log('>>' + content); throw new Error('haha error!'); }); }). fail(function(err){ console.log('err>>' + err); });
所谓的链式调用就是在成功回调内返回一个新的promise对象,假如之后的回调不需要获取闭包内容的话,可以直接返回,否则可以接着写then方法调用
总结
q.js是一个非常好用的promise实现,前后端都可以用,像ng里就有一个$q的实现,强烈推荐大家使用这个.
实例
var Q = require('q'); //用Q整合的函数都是调用mongoose的,返回查询表的结果或者创建新表 var findUserByNickname = Q.nfbind(UserProfileModel.findUserByNickname.bind(UserProfileModel)); //Q.nfbind 和Q.denodeify是一个东西,同名而已。 //使用 Q.defer()自定义合法返回的内容,注意要在回调函数外使用return deferred.promise的语法 var nameFind = function(exist){ var deferred = Q.defer(); if (exist) { message = "用户名重复"; deferred.resolve(1); return deferred.promise; }else{ UserProfileModel.findUserByEmail(email,function(err,user){ if (user) { deferred.resolve(1); message = "邮箱重复"; }else { deferred.resolve(0); }; }); return deferred.promise; }; } var emailFind = function(exist){ var deferred = Q.defer(); if (exist==0){ UserProfileModel.createSimpleUser(user_nickname,user_realname,email,password,userid,function(err,user){ deferred.resolve(user); message = "注册成功"; }); return deferred.promise; }else{ deferred.resolve(1); return deferred.promise; } } //最后直接调用函数的实例,function error自动收集error。 findUserByNickname(user_nickname) .then(nameFind) .then(emailFind) .then( function(data){ res.send(message); },function(error){ res.sendError("注册失败"); console.log(error); });
//Q 的使用一 var preadFile = function(file){ var deferred = Q.defer();// fs.readFile(file, "utf8",function(err,data){ if(!err){ deferred.resolve(data);//成功返回的数据 }else{ deferred.reject(err);//失败返回的错误信息 } }); return deferred.promise;//必须返回这个 } preadFile("foo.json").then(function (data) {//then方法有两个参数(成功回调,失败回调) console.log(data); }, function (error) { console.error(error); }); //Q 的 all组合方法(你可以把一系列promises到整个promises中) function test(value) { return Q.delay(value, 1000);//延迟1秒 } Q.all([ test(10),//执行三个函数 test(20), test(30) ]) .spread(function (x, y,z) {//三个函数返回的三个值 console.log(x, y,z); return x+y+z; }) .done(function(str){//完成前面的后执行 console.log(str) });
相关文章推荐
- Comet技术选择,论Is node.js best for Comet?
- Node.js: Building for Scalability with Server-Side JavaScript
- msnodesql 0.2.1 for node.js 0.10.x
- node.js Tools for Visual Studio 介绍
- Building a Redis Sentinel Client for Node.js
- ExpressJS for NodeJS 开发(草稿)
- How naive it's to believe node.js good for IO but bad for Computation?
- Adding timeout support for http request in Node.JS
- 构筑RubyMine IDE开发工具的Coffeescript+node.js开发环境(for windows)
- bearcat a POJOs based application framework for node.js
- Is node.js best for Comet?
- nowjs for Node - Directly call remote functions in Javascript
- Is node.js best for Comet?
- 安装选择构筑RubyMine IDE开发工具的Coffeescript+node.js开发环境(for windows)
- Vim Plugins For Node.js
- NodeJS for Windows
- NodeJS For Windows
- nodejs for windows
- Nodejs+express For mac
- Node.js 101(2): Promise and async