日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

NodeJs回调操作Promise化

發(fā)布時間:2024/4/17 编程问答 45 豆豆
生活随笔 收集整理的這篇文章主要介紹了 NodeJs回调操作Promise化 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

mongoose是一個NodeJs下MongoDB的ORM庫。使用這個庫,您從DB到表(collection)都不用創(chuàng)建了。只需要在項目中定義好Model。

下面就是用上一篇的代碼來演示如何把mongoose的數(shù)據(jù)庫操作里的回調(diào)地獄(callback hell)輕松化解掉。

上一篇Petshop的代碼在這里。

打開Promise的開關(guān)

mongoose已經(jīng)開啟了對Promise的支持,只需要指定明確的Promise庫就可以:

var mongoose = require('mongoose'),Promise = require('bluebird');

本來每一個model的定義都需要引入mongoose庫,然后每次都給mongoose庫指定Promise庫太過冗繁。所以我們抽象代碼,在models目錄下創(chuàng)建一個base目錄,然后在里面添加一個index.js文件:

//petshop/server/models/index.jsvar mongoose = require('mongoose'),Promise = require('bluebird');mongoose.Promise = Promise;module.exports = mongoose;

然后在model的定義都是用export的添加Promise的mongoose:

var mongoose = require('./base'),bcrypt = require('bcrypt-nodejs');var Schema = mongoose.Schema;var userSchema = new Schema({username: {type: String, unique: true, required: true},password: {type: String, required: true} });...module.exports = mongoose.model('User', userSchema);

這樣,使用了base目錄下的mongoose定義的model都具備了Promise的能力。

在調(diào)用查找更新等方法的時候只需要這樣:

User.findOne({ username: username }).exec().then(function (u) {if (!u) {done(null, false);return;}var verifyPasswordAsync = Promise.promisify(u.verifyPassword, { context: u });verifyPasswordAsync(password).then(function (match) {console.log('password match ' + match);if (!match) {console.log('is match ' + match);done(null, false);} else {done(null, u);}});}).catch(function (err) {done(err);});

解釋如下:
第一行代碼User.findOne({ username: username }).exec()在exec調(diào)用之后就返回了一個Promise。后面就可以使用Promise的then方法來開始Promise的方式依次調(diào)用和異常處理了。

單獨promise化一個方法

在mongoose內(nèi)置的Promise支持不能完成某些方法的時候還可以另外使用bluebird庫來單獨的針對這個方法來使其promise化。比如上例的u.verifyPassword代碼:

userSchema.methods.verifyPassword = function (password, callback) {bcrypt.compare(password, this.password, function (err, match) {if (err) {return callback(err);}callback(null, match);}); };

單獨的promise化verifyPassword方法:

var verifyPasswordAsync = Promise.promisify(u.verifyPassword, { context: u });

之后的使用:

verifyPasswordAsync(password).then(function (match) {console.log('password match ' + match);if (!match) {console.log('is match ' + match);done(null, false);} else {done(null, u);} });

Promise化的一般原則

對于上面例子這里稍作引申。Promise化的時候使用的是bluebird庫。

下面使用的例子代碼如下:

function Dog(name) {this.name = !name ? 'Tiger': name; }Dog.prototype.bite = function(target, cb){console.log(this.name + ' bite ' + target);cb(null, target); };

Promise化一個對象

Promise化一個對象使用promisifyAll方法。

var Promise = require('bluebird');var d = Promise.promisifyAll(new Dog()); d.biteAsync('hellokitty');

輸出:

Tiger bite hellokitty

注意:Promise化之后調(diào)用方法需要加上Async后綴。bite=>biteAsync。

Promise化一個方法

Promise化的是一個帶有回調(diào)的方法。這個Promise返回的結(jié)果就是回調(diào)正確的情況下獲得的值。

var someDog = new Dog("small"); var otherDog = new Dog("big"); var proDog = Promise.promisify(someDog.bite, {context: otherDog}); proDog('YOU').then(function(target) {console.log('then ' + target);walk(); })

在Promise話一個方法的時候需要考慮是不是指定context。上例中如果不指定context的時候會報錯。一般,如果是require引入的庫的方法不需要指定context,但是局部變量需要制定。指定context以后,方法的this指向的上下文就是這個context對象。

總結(jié)

Promise化之后,回調(diào)地獄的問題就有很好的解決了。不過,還需要考慮項目的大小和回調(diào)的深度來決定是否要Promise化。畢竟Promise會增加一定的代碼量,也有一定的學(xué)習(xí)曲線。

歡迎加群互相學(xué)習(xí),共同進步。QQ群:iOS: 58099570 | Android: 572064792 | Nodejs:329118122 做人要厚道,轉(zhuǎn)載請注明出處!

















本文轉(zhuǎn)自張昺華-sky博客園博客,原文鏈接:http://www.cnblogs.com/sunshine-anycall/p/5654115.html,如需轉(zhuǎn)載請自行聯(lián)系原作者

總結(jié)

以上是生活随笔為你收集整理的NodeJs回调操作Promise化的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。