html form callback,Promise异步编程模式总结初始化Promise对象统一错误处理PromisifyfromCallbackMongoose Promisify...

Promise是JavaScript中的一种异步编程范式, 一个Promise对象表示一个即将完成但还未完成的操作。 鉴于JavaScript中异步和回调的编程风格, Promise模式可以有效地避免『Callback Hell』。

Promise 最初有q和bluebird等实现,在ES2015(ES6)提出后Promise已经进入标准,Node.js已经开始支持ES6的很多特性,包括Promise。

初始化

传入一个回调函数即可初始化一个Promise对象padmin:

var padmin = new Promise(function(resolve, reject){

user.find({role: 'admin'}, function(err, admins){

if(err) reject(err);

else resolve(admins);

});

});

除此之外,ES6还给出4种常用的初始化方式,下列方法均返回一个Promise对象:

方法

说明

Promise.all(iterable)

当iterable(比如数组)中所有Promise都resolve时,该Promise resolve;iterable中任何一个被reject,则该Promise被reject

Promise.race(iterable)

当iterable中任意一个Promise被resolve或reject,该Promise都会相应地结束

Promise.reject(err)

直接返回一个被reject的Promise对象

Promise.reject(value)

直接返回一个被resolve的Promise对象

Promise对象

Promise对象padmin拥有两个主要方法:

方法

说明

Promise.prototype.catch(onRejected)

当一个Promise被reject时调用onRejected

Promise.prototype.then(onFulfilled, onRejected)

当一个Promise被resolve时调用onFulfilled,被reject时调用onRejected

上述两个方法均返回一个Promise,这意味着.then和.catch可以链式书写。例如:

padmin

.then(function(admins){

doSthWith(admins);

})

.catch(function(err){

console.error(err);

});

统一错误处理

在任何一个then()回调中抛出的错误都会被后面的catch()所截获,以此可以做统一的错误处理:

padmin

.then(function(admins){

if(admins === null) throw new Error('query admin error');

return admins.length;

})

.then(function(length){

if(length === 0) throw new Error('empty admin list');

console.log(length + ' admins in total.');

})

.catch(function(err){

console.error(err);

});

Promisify

Node.js的内置库以及大量的NPM工具都采用『Error-First Callback』风格,例如:

fs.readFile('foo.txt', function(err, content){

if(err) console.error(err);

else console.log(content);

});

在Promise风格的代码中,通常会需要readFile返回一个Promise对象,于是常常会这样包装该API:

var readFileAsync = function(path){

return new Promise(function(resolve, reject){

fs.readFile(path, function(err, content){

if(err) reject(err);

else resolve(content);

});

});

}

readFileAsync('foo.txt')

.then(function(content){

console.log(content):

})

.catch(function(err){

console.error(err);

});

然而我们需要包装fs模块下的所有API 🙁 bluebird为此提供了有用的方法promisifyAll():

var fs = require("fs");

// 为fs的所有方法创建一个Promise包装,命名为xxxAsync

Promise.promisifyAll(fs);

fs.readFileAsync("foo.txt").then(...).catch(...);

当然也可以只包装一个函数:

var readFile = Promise.promisify(require("fs").readFile);

readFile("foo.txt").then(...).catch(...);

fromCallback

现在我们有了.promisify来把一个『Error-First Callback』风格的API包装为Promise风格。 在某些特定情形下,可能每次使用都需要先进行promisify,比如使用后即被销毁的临时对象。 例如从HTTP请求构造的req对象每次请求都是新的:

function(req, res, next){

User.find({name: req.body.name})

.then(function(user) {

var login = Promise.promisify(req.login);

return login.call(req, user);

})

.catch(next);

}

这时可以用Promise.fromCallback方法,直接由『Error-First Callback』调用生成Promise对象,而不需要生成Promise风格的方法。

function(req, res, next){

User.find({name: req.body.name})

.then(function(user) {

return BPromise.fromCallback(cb => req.login(user, cb));

})

.catch(next);

}

Mongoose Promisify

mongoose是MongoDB在JavaScript下的适配器(类似ORM),提供了模型验证、数据转换、业务逻辑钩子、查询钩子等对象建模工具。 mongoose有些API(如.exec())会返回内置的Promise,我们可以用一个更强的Promise来替代它:

var BPromise = require('bluebird');

mongoose.Promise = BPromise;

除exec(), execPopulate()系列函数外,mongoose多数API都是回调风格的,通常需要用Bluebird将其Promisify。 这些Mongoose API主要包括下列三类:

Model. Eg: User.findAsync(), User.findByIdAsync(), User.removeAsync(), User.updateAsync()

Model.prototype. Eg: user.saveAsync(), user.removeAsync()

Query.prototype. Eg: User.find().sortAsync(), User.find().populateAsync()

BPromise.promisifyAll(mongoose.Model);

BPromise.promisifyAll(mongoose.Model.prototype);

BPromise.promisifyAll(mongoose.Query.prototype);

这些Promise化的代码最好在代码载入时执行,但不要早于mongoose插件。否则这些插件就不会被Promise化了。

Promise化之后的mongoose用起来是这样的:

var UserSchema = mongoose.Schema({

name: String,

phone: String

});

var User = mongoose.model('User', UserSchema);

User.findAsync()

.then(users => console.log(users));

.catch(e => console.error(e));

某些mongoose插件可能需要在Promisify脚本之后执行较为方便。这时我们需要将受影响的模型再次Promise化:

var UserSchema = mongoose.Schema({...});

UserSchema.plugin(require('passport-local-mongoose'), {

usernameField: 'phone'

});

var User = mongoose.model('User', UserSchema);

BPromise.promisifyAll(User);

文章出处

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/534059.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

常用命令_GIT常用命令大全

Git 是一个很强大的分布式版本控制系统。它不但适用于管理大型开源软件的源代码,管理私人的文档和源代码也有很多优势。克隆远程文件:git clone https://gitee.com/abcd/codefile.git projectgit checkout -b dev(本地分支名称) origin/dev(远程分支名称…

nvidia显示设置不可用_Nvidia显示设置不可用,您当前未使用连接到NVIDIA GPU的显示器的解决方法...

相信不少用户遇到这样一个问题,就是新购买的台式机电脑,配置达标的情况下,玩游戏出现卡顿不流畅的现象,准备在NVIDIA控制面板查看是否设置的问题,在打开NVIDIA控制面板的时候,提示了“Nvidia显示设置不可用…

html的id不能有.吗,html – 哪些DOM元素不能接受id?

在HTML5中,id属性是global attribute,可以在任何元素上指定.如果你看看Document Type Declaration for HTML4,你可以找到没有%attrs的元素;在他们的属性列表中定义,表示它们不支持id属性.那些包括在“文档头”部分的底部附近:HEAD,TITLE,BASE,META,STYLE…

oracle tns 代理配置_Toad for oracle安装配置与使用

一.toad安装与配置注意:toad的使用本机电脑必须安装完整版oracle客户端,不能是精简版的.1.1完整版oracle客户端的安装.1.解压文件,安装oracle客户端打开安装包,找到setup.ext,开始安装。提示下图弹窗,可根据此网址内容进行更改(https://blog.…

吴枫 python小课账号_无门槛速学编程——Python小短课,自上而下分而治之

【Python小短课 11】自上而下,分而治之 做任何事都需计划,编程也是。 譬如写文章要列大纲、作画要想布局,编程也需先谋全局,而后思虑细节。 就以上回说到的“找宝藏”这个程序举例,最顶层的需求自然就是“找宝藏”&…

计算机本地磁盘D无法扩展,计算机上的本地磁盘D突然无法打开,表明它需要格式化...

接受使用数据恢复软件将重要数据保存到其他磁盘FindDate特定操作: 运行软件----“打开”后,将显示要还原的驱动器. C \ D \ E \ F选择您要还原的一个,它将开始. 扫描后,再次保存扫描的文件. 哈哈,希望对您有所帮助.最后&#xff0…

caffe运行不停止_caffe(gpu)安装过程及问题解决

2019.12.05 caffe(gpu)安装参考网址:教程1:weiliu89/caffe​github.com教程2:https://blog.csdn.net/yggaoeecs/article/details/79163789​blog.csdn.net环境:Ubuntu16.04cuda10.0安装过程:git clone https://github.…

2021年考计算机考研三战,2021考研的小伙伴有3条忠告一定要记得,这些都是历年实战经验...

2021考研的小伙伴有3条忠告一定要记得,这些都是历年实战经验,考研一定要记得避开三个大坑。1,分数线低的学校就一定容易考。有一些学校分数线看着很低但实际上难度不低,比如首都师范大学 ,很多专业就是国家线录取甚至招…

c++ 返回string_JVM系列之:String.intern和stringTable

简介StringTable是什么?它和String.intern有什么关系呢?在字符串对象的创建过程中,StringTable有起到了什么作用呢?一切的答案都在本文中,快来看看吧。intern简介intern是String类中的一个native方法,所以它…

conda install 换源_ubuntu更换pip install,apt-get,conda install 成国内源

# 默认注释了源码镜像以提高 apt update 速度,如有需要可自行取消注释deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ xenial main restricted universe multiverse# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ xenial main restricted universe mu…

python帮助文档中查看内置函数_PYTHON官方文档内置函数整理

一、数学运算类 abs(x) 求绝对值 1 、参数可以是整型,也可以是复数 2 、若参数是复数,则返回复数的模 complex([real[, imag]]) 创建一个复数 divmod(a, b) 分别取商和余数 注意:整型、浮点型都可以 float([x]) 将一个字符串或数转换为浮点数…

计算机二级指针,C语言——二级指针

二级指针的概念首先任何值都有地址,一级指针的值虽然是地址,但这个地址做为一个值亦需要空间来存放,是空间就具有地址,这就是存放地址这一值的空间所具有的地址,二级指针就是为了获取这个地址,一级指针所关…

华为 虚拟键盘_华为mate30 pro虚拟机械键盘特有体验,虽是虚拟,但却感受逼真...

华为Mate30 pro已于26日在国内正式发布了。此外,根据了解华为Mate30系列现在已经突破了5亿的销售额。看来,华为的这个下半年旗舰手机非常受欢迎啊。华为Mate30系列现在在国内已经发布了,其整体感官看上去与海外的没有多大的区别。其实&#x…

python 如何快速判断列表是否相同_Python-检查列表中的所有元素是否相同

小编典典 通用方法: def checkEqual1(iterator): iterator iter(iterator) try: first next(iterator) except StopIteration: return True return all(first rest for rest in iterator) 单线: def checkEqual2(iterator): return len(set(iterator)…

计算机有什么著名基金经理排名,百万年薪的基金经理,都是什么专业出身?!...

有人会说了“小哔君你四不四撒!基金经理肯定是金融专业出身的咯?不然嘞?”但事实的真相是许多基金经理都并非科班出身这要从基金经理的晋升机制说起了!如下图基金经理都是从研究员做起的!那么问题来了,如何…

遍历children_589. N叉树的前序遍历

589. N叉树的前序遍历给定一个 N 叉树,返回其节点值的前序遍历。例如,给定一个 3叉树 :返回其前序遍历: [1,3,5,6,2,4]。说明: 递归法很简单,你可以使用迭代法完成此题吗?题解:既然是树的遍历,那么一共就是两种思路&a…

计算机护理职称考试报名时间2015,护理职称考试怎么报名?

护理职称考试报名流程:网上预报名-现场确认-报名缴费。护理职称考试网上预报名及网上缴费均在中国卫生人才网,护理职称考试报名现场确认则按属地原则在单位或户籍所在地的卫计局。护理职称考试报名流程详解一、网上预报名考生需在规定的时间内登录中国卫…

怎么用python编程前二n-1项的等差数列的和_python 等差数列末项计算方式

等差数列末项计算 题目内容: 给出一个等差数列的前两项a1,a2,求第n项是多少 可以使用以下语句实现非负整数n的输入: nint(input()) 输入格式: 三行,包含三个整数a1,a2,n 输出格式: 一…

图纸中bs是什么意思_园建施工图中WL、BL、FL、TW、SL分别是什么意思

展开全部WL是水面标高来BL池底自标高FL地面标bai高TW墙顶标高SL 土面标高其他其他一些常du用的注解:PA种植区FF室内楼zhi地面标FG室外软景完成dao面标高BC路沿底标高BS踏步底标高BR栏杆扶手底标高TR栏杆扶手顶标高SL结构板顶标高扩展资料本书围绕园林工程建设主题&a…

计算机未显示移动硬盘,电脑不显示移动硬盘怎么办_移动硬盘已连接不显示解决教程...

最近有很多小伙伴咨询小编,电脑不显示移动硬盘怎么办,怎么设置才能恢复呢?其实操作内容很简单,尝试删除你的USB3.0可扩展主机控制器,再扫描硬件改动,今天就由小编来告诉你,移动硬盘已连接不显示的解决方法。…