Bluebird中promisify的用法
来源:互联网 发布:k均值聚类算法matlab 编辑:程序博客网 时间:2024/05/16 18:16
Bluebird中promisify的用法
之前应项目需要,在node.js中引入bluebird包学习使用Promise。其链式结构的异步操作容易理解,也减少了回调函数的多层嵌套。网络上对Promise的介绍已经比较全面,这里不再赘述。本文主要从实际工作遇到的问题出发,介绍其promisify方法的使用。
New一个Promise对象的缺点
创建一个新的Promise对象代码如下:
var Promise = require('bluebird');var promiseObj = new Promise(function(resolve, reject) { var isJudged = false, result = ''; // some logic deal code // ... // get judgement if (isJudged) { resolve(result); } else if (!isJudged) { reject('Something wrong'); }});
我们知道Promise对象存在三种状态:Pending,Resolved和Rejected。当我们的代码执行完一系列的操作,最后进行判断需不需要将运算出的结果返还回去,如果需要,那么我们使用resolve(result);这句代码返回结果,如果不需要,那么我们使用reject(‘Something wrong’);这句代码返回错误信息。二者决定我们在使用此Promise对象时的.then方法是进入Resolved状态的Function还是Rejected状态的Function。
var z = promiseObj.then(function(result){ // Resolved }, function(error) { // Rejected});
从上面代码可以读出,PromiseObj包含一个then方法,then方法中通过自身状态决定使用哪一个回调函数,那么PromiseObj中存在一个属性保存自身的状态,这条状态的值依赖于我们在new Promise对象时所传入的function中的代码。
实际上,我们在new Promise对象时,传入的function中的代码就立即执行了,Promise对象迫不及待地想得到一个状态值(Resolved也好Rejected也好)。在某些场景应用中,这并非我们所想要的。比如在不同流程中都包含同样一个步骤的Promise,在每个流程中我们都需要重新new一个相同的Promise对象来保证每个流程的运转正常。假如我们只使用一个Promise,那么这个Promise在new出来的那一刻起,就获取当前的context变量开始运行,期望得到一种结果状态。而对于不同流程,它们各自的context变量是存在差异的,因而使用同一个Promise对象会产生预估之外的问题,而对不同流程使用不同Promise的做法看上去又相当麻烦且代码冗长。
我们需要一种Promise型的对象(异步且可用.then的形式执行回调函数),这时候我们可以使用promisify方法。
Promisify
promisify旨在解决使用Promise的方式调用那些没有使用Promise的模块中的方法。这么说可能比较绕。请看官网上解释promisify使用方法的一段代码:
var readFile = Promise.promisify(require("fs").readFile);readFile("myfile.js", "utf8").then(function(contents) { return eval(contents);}).then(function(result) { console.log("The result of evaluating myfile.js", result);}).catch(SyntaxError, function(e) { console.log("File had syntax error", e);//Catch any other error}).catch(function(e) { console.log("Error reading file", e);});
这里将fs模块中读取文件的readFile转化为了Promise形式的异步方法。现实应用这样的场景也不少,我们需要将一个之前定义好的方法转化为异步的形式。下面将详细介绍如何使用promisify。
var Promise = require('bluebird');var normalFn = function(a, b, c, cb) { /** * your own logic code */ var t = a + b + c; if (typeof cb == 'function') { cb('', t); }};var promisifyFn = Promise.promisify(normalFn);promisifyFn('hello, ', 'world', '!').then(function(result){ console.log(result);}, function(error) { console.log(error);});
根据上例,我们必须满足以下条件方可使用promisify进行转换。
- 原方法必须包含回调函数(cb(”, t);)
- 必须执行回调函数,目的是决定在完成中间整块逻辑代码后,获取最终方法的的状态(Resolved或Rejected)以便选择进入哪个真实的.then之后的回调函数。
- 回调函数第一个参数代表error的信息,第二个参数代表成功时返回的结果。error为空值,则后续可进入Resoleved的方法,若不为空值,则后续进入Rejected方法
不同于声明一个Promise对象,我们在声明一个promisifyFn时并不会立即去执行其间的逻辑代码,而是将一个普通的函数转化为了一个返回Promise对象的函数,当我们真正调用这个函数的时候,其间的代码才真正的运行。
官网对其定义如下:
Promise.promisify( function(any arguments..., function callback) nodeFunction, [Object { multiArgs: boolean=false, context: any=this } options]) -> function
我们在使用promisify时可以设定一些参数,比如context执行上下文,和multiArgs。如果multiArgs设定为true,那么我们在执行cb(”, t);时可以传入多个成功的值,即除了第一个参数绑定为error以外,我们可以在后续的参数中加入我们想添加的任何对象。最终这些传入的参数反应为执行Resolved函数的参数,即.then(function(result) { console.log(result); },。multiArgs为true,那么result是cb传入参数的一个数组对象;multiArgs为false,那么result是cb传入参数的第二个,尽管cb会传入大于两个的参数。
- Bluebird中promisify的用法
- 基于es6的promisify
- Bluebird-NodeJs的Promise
- 在mongoose中使用bluebird
- Callback 与 Promise 间的桥梁 —— promisify
- mongoose数据查询之bluebird的使用
- nodejs-使用request和bluebird编写的http请求模块
- wilddog(野狗)js sdk和promise(bluebird)的结合使用
- 利用bluebird的promise 实现nodejs http下载异步调用的同步逻辑
- bluebird--ie插件
- Bluebird 高性能揭秘
- Promise-Bluebird源码
- bluebird之catch
- C++中“::”的用法
- C#中 @ 的用法
- 中UserMap的用法
- c#中@的用法
- C#中@的用法
- Android 反射的使用
- Longest Valid Parentheses
- poj 3308 Paratroopers最小点权覆盖
- C++ 智能指针详解
- 详细介绍C++中的类对象内存模型
- Bluebird中promisify的用法
- Hama共享内存通信问题
- 1119. Pre- and Post-order Traversals
- Joda-Time入门
- leetcode刷题之旅——53. Maximum Subarray
- android自定义Adapter
- 倒计时 小demo
- 基于单链表的快排
- 翻转一个数字(不知其有多少位)