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.pswp.cn/news/534059.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/534059.shtml
英文地址,請注明出處:http://en.pswp.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可擴展主機控制器,再掃描硬件改動,今天就由小編來告訴你,移動硬盤已連接不顯示的解決方法。…