AngularJS中$q.when()的用法實(shí)例解析
一、$q.when()的定義與作用
1. 方法定義
$q.when(value);
2. 核心作用
$q.when() 用于將一個(gè)值(同步或異步)統(tǒng)一包裝為 $q Promise 對(duì)象。
其本質(zhì)目標(biāo)是:
屏蔽同步值與異步 Promise 的差異,使調(diào)用方始終以 Promise 的方式進(jìn)行處理。
二、$q.when()的參數(shù)與返回值
1. 參數(shù)類(lèi)型
value 可以是以下任意一種:
| 參數(shù)類(lèi)型 | 行為 |
|---|---|
| 普通值(number、string、object 等) | 立即 resolve |
$q Promise | 直接返回(或狀態(tài)跟隨) |
thenable 對(duì)象(含 then 方法) | 按 Promise 規(guī)則解析 |
| 原生 ES6 Promise | 自動(dòng)橋接為 $q Promise |
2. 返回值
$q.when(...) → Promise
返回的是一個(gè) $q Promise 對(duì)象,其狀態(tài)由傳入?yún)?shù)決定。
三、不同輸入情況下的具體行為
1. 傳入普通同步值
$q.when(100).then(function (value) {
console.log(value); // 100
});
行為說(shuō)明:
- Promise 狀態(tài):
fulfilled - 回調(diào)在 下一輪 digest 周期中執(zhí)行
- 不會(huì)同步立即執(zhí)行回調(diào)
2. 傳入$qPromise
var p = $q.defer().promise;
$q.when(p).then(function (value) {
console.log(value);
});行為說(shuō)明:
- 不創(chuàng)建新的異步邏輯
- 返回的 Promise 狀態(tài)與原 Promise 保持一致
- 等價(jià)于直接使用
p.then(...)
3. 傳入 thenable 對(duì)象
var thenable = {
then: function (resolve, reject) {
resolve('ok');
}
};
$q.when(thenable).then(function (value) {
console.log(value); // ok
});行為說(shuō)明:
$q.when()會(huì)調(diào)用其then方法- 符合 Promises/A+ 的解析流程
- 防止第三方庫(kù) Promise 失配
4. 傳入原生 ES6 Promise
var nativePromise = Promise.resolve('hello');
$q.when(nativePromise).then(function (value) {
console.log(value); // hello
});行為說(shuō)明:
$q會(huì)監(jiān)聽(tīng)原生 Promise 的結(jié)果- 自動(dòng)觸發(fā) AngularJS 的
$digest - 解決“視圖不刷新”問(wèn)題
四、$q.when()與$q.resolve()的關(guān)系
1. 等價(jià)性說(shuō)明
在 AngularJS 1.4+ 版本中:
$q.when(value) === $q.resolve(value)
$q.resolve()是語(yǔ)義更清晰的新 API$q.when()為歷史兼容方法
2. 推薦實(shí)踐
- 新代碼:優(yōu)先使用
$q.resolve() - 舊項(xiàng)目:
$q.when()仍然完全可用
五、$q.when()的執(zhí)行時(shí)機(jī)與 Digest 機(jī)制
1. 回調(diào)執(zhí)行模型
$q.when(value).then(callback);
callback永遠(yuǎn)是異步執(zhí)行- 執(zhí)行時(shí)機(jī):當(dāng)前調(diào)用棧完成后
- 必定處于
$digest環(huán)境中
2. 與原生 Promise 的關(guān)鍵區(qū)別
| 對(duì)比項(xiàng) | $q.when() | Promise.resolve() |
|---|---|---|
觸發(fā) $digest | 是 | 否 |
| Angular 視圖更新 | 自動(dòng) | 需 $apply |
| 框架集成 | 深度 | 無(wú) |
六、典型使用場(chǎng)景(重點(diǎn))
場(chǎng)景一:統(tǒng)一同步與異步接口
function getConfig() {
if (cache) {
return $q.when(cache);
}
return $http.get('/config').then(function (res) {
return res.data;
});
}調(diào)用方:
getConfig().then(function (config) {
// 不關(guān)心是緩存還是網(wǎng)絡(luò)
});
? 這是 $q.when() 最重要、最典型的用途
場(chǎng)景二:函數(shù)返回值 Promise 化
function normalize(value) {
return $q.when(value).then(function (v) {
return v.trim();
});
}
場(chǎng)景三:橋接第三方 Promise
function wrapThirdParty(promise) {
return $q.when(promise);
}
確保:
- 狀態(tài)可控
- digest 正常觸發(fā)
場(chǎng)景四:與$q.all()配合
$q.all([
$q.when(1),
$http.get('/api'),
maybePromise
]).then(function (results) {
console.log(results);
});七、$q.when()與$q.defer()的對(duì)比
| 維度 | $q.when() | $q.defer() |
|---|---|---|
| 是否創(chuàng)建新 Promise | 是(輕量) | 是(完整) |
| 是否控制 resolve | 否 | 是 |
| 適用場(chǎng)景 | 包裝、統(tǒng)一接口 | 主動(dòng)控制異步流程 |
| 推薦程度 | 高 | 謹(jǐn)慎使用 |
能用
$q.when()的地方,通常不應(yīng)使用$q.defer()
八、常見(jiàn)誤區(qū)與注意事項(xiàng)
1. 誤區(qū):認(rèn)為$q.when()是同步執(zhí)行
? 錯(cuò)誤認(rèn)知
?? 實(shí)際上始終異步
2. 誤區(qū):用$q.when()代替業(yè)務(wù)邏輯判斷
// 不推薦 return $q.when(flag ? value1 : value2);
可讀性不佳,應(yīng)合理拆分邏輯。
3. 注意:異常處理規(guī)則
$q.when(value).then(function () {
throw new Error('error');
}).catch(function (e) {
console.error(e);
});
throw會(huì)自動(dòng)轉(zhuǎn)為reject
九、總結(jié)
$q.when() 的本質(zhì)可以概括為一句話:
將一切“可能是異步的東西”,統(tǒng)一為一個(gè)可控、可組合、可追蹤的
$qPromise。
其工程價(jià)值體現(xiàn)在:
- 簡(jiǎn)化接口設(shè)計(jì)
- 提升可維護(hù)性
- 消除同步 / 異步分支
- 與 AngularJS 變更檢測(cè)機(jī)制完美協(xié)同
到此這篇關(guān)于AngularJS中$q.when()的用法的文章就介紹到這了,更多相關(guān)AngularJS $q.when()用法內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
詳解使用angular框架離線你的應(yīng)用(pwa指南)
這篇文章主要介紹了詳解使用angular框架離線你的應(yīng)用(pwa指南),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2019-01-01
AngularJS中的包含詳細(xì)介紹及實(shí)現(xiàn)示例
本文主要介紹AngularJS 包含,這里對(duì)相關(guān)資料做了詳細(xì)整理,并附代碼實(shí)例和效果圖,有需要的朋友可以看一下2016-07-07
AngularJS單選框及多選框?qū)崿F(xiàn)雙向動(dòng)態(tài)綁定
這篇文章主要為大家詳細(xì)介紹了AngularJS單選框及多選框?qū)崿F(xiàn)雙向動(dòng)態(tài)綁定的相關(guān)資料,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-01-01
基于angular實(shí)現(xiàn)模擬微信小程序swiper組件
這篇文章主要介紹了基于angular實(shí)現(xiàn)模擬微信小程序swiper組件 ,需要的朋友可以參考下2017-06-06
Angular實(shí)現(xiàn)搜索框及價(jià)格上下限功能
這篇文章主要為大家詳細(xì)介紹了Angular實(shí)現(xiàn)搜索框及價(jià)格上下限功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-01-01
AngularJS全局警告框?qū)崿F(xiàn)方法示例
這篇文章主要介紹了AngularJS全局警告框?qū)崿F(xiàn)方法,結(jié)合實(shí)例形式分析了AngularJS全局警告框的實(shí)現(xiàn)步驟與相關(guān)操作技巧,需要的朋友可以參考下2017-05-05
使用Angular 6創(chuàng)建各種動(dòng)畫(huà)效果的方法
Angular能夠讓我們創(chuàng)建出具有原生表現(xiàn)效果的動(dòng)畫(huà)。我們將通過(guò)本文學(xué)習(xí)到如何使用Angular 6來(lái)創(chuàng)建各種動(dòng)畫(huà)效果。在此,我們將使用Visual Studio Code來(lái)進(jìn)行示例演示。感興趣的朋友跟隨小編一起看看吧2018-10-10

