最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

jQuery源碼分析-05異步隊列 Deferred 使用介紹

 更新時間:2011年11月14日 23:51:41   作者:  
異步隊列是一個鏈式對象,增強對回調(diào)函數(shù)的管理和調(diào)用,用于處理異步任務
5. 異步隊列 Deferred
5.1 概述
異步隊列是一個鏈式對象,增強對回調(diào)函數(shù)的管理和調(diào)用,用于處理異步任務。
異步隊列有三種狀態(tài):初始化(unresolved),成功(resolved),失敗(rejected)。
執(zhí)行哪些回調(diào)函數(shù)依賴于狀態(tài)。
狀態(tài)變?yōu)槌晒Γ╮esolved)或失?。╮ejected)后,將保持不變。
回調(diào)函數(shù)的綁定可以是同步,也可以是異步的,即可以在任何時候綁定。
(本節(jié)中的 綁定 注冊 增加 具有相同的含義)
5.2 關鍵方法
先看看jQuery. Deferred()中的關鍵方法
分類
方法
說明
增加
deferred.done()
增加成功回調(diào)函數(shù)
狀態(tài)為成功(resolved)時立即調(diào)用
deferred.fail()
增加失敗回調(diào)函數(shù)
狀態(tài)為失?。╮ejected)時立即調(diào)用
deferred.then()
增加成功回調(diào)函數(shù)和失敗回調(diào)函數(shù)到各自的隊列中
便捷方法,兩個參數(shù)可以是數(shù)組或null
狀態(tài)為成功(resolved)時立即調(diào)用成功回調(diào)函數(shù)
狀態(tài)為失?。╮ejected)時立即調(diào)用失敗回調(diào)函數(shù)
deferred.always()
增加回調(diào)函數(shù),同時增加到成功隊列和失敗隊列
狀態(tài)已確定(無論成功或失?。r立即調(diào)用回調(diào)函數(shù)
執(zhí)行
deferred.resolve()
調(diào)用成功回調(diào)函數(shù)隊列
通過調(diào)用deferred.resolveWith()實現(xiàn)
deferred.resolveWith()
使用指定的上下文和參數(shù)執(zhí)行成功回調(diào)函數(shù)
deferred.reject()
調(diào)用失敗回調(diào)函數(shù)隊列
通過調(diào)用deferred.rejectWith()實現(xiàn)
deferred.rejectWith()
使用指定的上下文和參數(shù)執(zhí)行失敗回調(diào)函數(shù)隊列
其他
deferred.isRejected()
判斷狀態(tài)是否為成功(resolved)
deferred.isResolved()
判斷狀態(tài)是否為失?。╮ejected)
deferred.pipe()
每次調(diào)用回調(diào)函數(shù)之前先調(diào)用傳入的成功過濾函數(shù)或失敗過濾函數(shù),并將過濾函數(shù)的返回值作為回調(diào)函數(shù)的參數(shù)
最終返回一個只讀視圖(調(diào)用promise實現(xiàn))
deferred.promise()
返回deferred的只讀視圖
接下來將會jQuery._Deferred和jQuery.Deferred的源碼詳細剖析。


5.3 jQuery._Deferred
復制代碼 代碼如下:

局部變量
// 參考資料:
// 官網(wǎng)文檔 http://api.jquery.com/category/deferred-object/
// Deferred機制 http://www.cnblogs.com/fjzhou/archive/2011/05/30/jquery-source-3.html
// 在jQuery 1.5中使用deferred對象 http://developer.51cto.com/art/201103/248638.htm
// 拿著放大鏡看Promise http://www.cnblogs.com/sanshi/archive/2011/03/11/1981789.html
// Promises/A http://wiki.commonjs.org/wiki/Promises/A
var // Promise methods
// 注意,沒有以下方法:resolveWith resolve rejectWith reject pipe when cancel
// 即不允許調(diào)用resolve reject cancel等
promiseMethods = "done fail isResolved isRejected promise then always pipe".split( " " ),
// Static reference to slice
// 靜態(tài)引用slice方法,借雞生蛋
sliceDeferred = [].slice;
_Deferred:
_Deferred: function() {
var // callbacks list
// 回調(diào)函數(shù)數(shù)組(這里不翻譯為隊列,避免概念上的混淆)
callbacks = [],
// stored [ context , args ]
// 存儲上下文、參數(shù),同時還可以標識是否執(zhí)行完成(fired非空即表示已完成)
// 這里的“完成”指回調(diào)函數(shù)數(shù)組中“已有”的函數(shù)都已執(zhí)行完成;
// 但是可以再次調(diào)用done添加回調(diào)函數(shù),添加時fired會被重置為0
fired,
// to avoid firing when already doing so
// 如果已經(jīng)觸發(fā)正在執(zhí)行,避免再次觸發(fā)
firing,
// flag to know if the deferred has been cancelled
// 標識異步隊列是否已被取消,取消后將忽略對done resolve resolveWith的調(diào)用
cancelled,
// 異步隊列定義(這才是正主,上邊的局部變量通過閉包引用)
// the deferred itself
deferred = {
// done( f1, f2, ...)
// 增加成功回調(diào)函數(shù),狀態(tài)為成功(resolved)時立即調(diào)用
done: function() {
// 如果已取消,則忽略本次調(diào)用
if ( !cancelled ) {
// 將后邊代碼用到的局部變量定義在代碼塊開始處的好處:
// 1.聲明變量,增加代碼可讀性;
// 2.共享變量,提高性能
// 注:多年寫Java的經(jīng)驗,養(yǎng)成了全局變量在開頭、臨時變量隨用隨定義的習慣,看來JavaScript有些不同
var args = arguments, // 回調(diào)函數(shù)數(shù)組
i, // 遍歷變量
length, // 回調(diào)函數(shù)數(shù)組長度
elem, // 單個回調(diào)函數(shù)
type, // elem類型
_fired; // 用于臨時備份fired(fired中存儲了上下文和參數(shù))
// 如果已執(zhí)行完成(即fired中保留了上下文和參數(shù))
// 則備份上下文和參數(shù)到_fired,同時將fired置為0
if ( fired ) {
_fired = fired;
fired = 0;
}
// 添加arguments中的函數(shù)到回調(diào)函數(shù)數(shù)組
for ( i = 0, length = args.length; i < length; i++ ) {
elem = args[ i ];
type = jQuery.type( elem );
// 如果是數(shù)組,則遞歸調(diào)用
if ( type === "array" ) {
// 強制指定上下文為deferred,個人認為這里沒必要指定上下文,因為默認的上下文即為deferred
deferred.done.apply( deferred, elem );
} else if ( type === "function" ) {
callbacks.push( elem );
}
}
// 如果已執(zhí)行(_fired表示Deferred的狀態(tài)是確定的),則立即執(zhí)行新添加的函數(shù)
// 使用之前指定的上下文context和參數(shù)args
if ( _fired ) {
deferred.resolveWith( _fired[ 0 ], _fired[ 1 ] );
}
}
return this;
},
// resolve with given context and args
// 執(zhí)行,使用指定的上下文和參數(shù)
resolveWith: function( context, args ) {
// 滿足以下全部條件,才會執(zhí)行:沒有取消 沒有正在執(zhí)行 沒有執(zhí)行完成
// 如果已取消 或 已執(zhí)行完成 或 正在執(zhí)行,則忽略本次調(diào)用
if ( !cancelled && !fired && !firing ) {
// make sure args are available (#8421)
// 確保args可用,一個避免null、undefined造成ReferenceError的常見技巧
args = args || [];
// 執(zhí)行過程中將firing改為1
firing = 1;
try {
// 遍歷動態(tài)數(shù)組的技巧
while( callbacks[ 0 ] ) {
// 注意這里使用指定的context,而不是this
callbacks.shift().apply( context, args );
}
}
// JavaScript支持try/catch/finally
finally {
fired = [ context, args ];
firing = 0;
}
}
return this;
},
// resolve with this as context and given arguments
// 把狀態(tài)設置為Resolved
// 設置的理解不準確,因為是否Resolved,是調(diào)用isResolved判斷firing、fired的狀態(tài)得到的。
// 可以理解為執(zhí)行
resolve: function() {
deferred.resolveWith( this, arguments );
return this;
},
// Has this deferred been resolved?
// 是否已執(zhí)行(或解決)?
// 在執(zhí)行或已執(zhí)行完畢,都認為已執(zhí)行/解決
// “已”可能不準確,因為執(zhí)行過程中也認為是已執(zhí)行
isResolved: function() {
// 正在運行中
// 或
// 已運行完(即fired不為空/0)
return !!( firing || fired );
},
// Cancel
// 取消異步隊列
// 設置標記位,清空函數(shù)隊列
cancel: function() {
cancelled = 1;
callbacks = [];
return this;
}
};
return deferred;
}

5.4 jQuery.Deferred
復制代碼 代碼如下:

// Full fledged deferred (two callbacks list)
// 創(chuàng)建一個完整的異步隊列(包含兩個回調(diào)函數(shù)數(shù)組)
// 異步隊列有三種狀態(tài):初始化(unresolved),成功(resolved),失?。╮ejected)。
// 執(zhí)行哪些回調(diào)函數(shù)依賴于狀態(tài)。
// 狀態(tài)變?yōu)槌晒Γ╮esolved)或失?。╮ejected)后,將保持不變。
Deferred: function( func ) {
// _Deferred本無成功狀態(tài)或失敗狀態(tài),有四種狀態(tài):初始化、執(zhí)行中、執(zhí)行完畢、已取消
// 為了代碼復用, 內(nèi)部先實現(xiàn)了一個_Deferred
// failDeferred通過閉包引用
var deferred = jQuery._Deferred(),
failDeferred = jQuery._Deferred(),
promise;
// Add errorDeferred methods, then and promise
jQuery.extend( deferred, {
// 增加成功回調(diào)函數(shù)和失敗回調(diào)函數(shù)到各自的隊列中
// 便捷方法,兩個參數(shù)可以是數(shù)組或null
// 狀態(tài)為成功(resolved)時立即調(diào)用成功回調(diào)函數(shù)
// 狀態(tài)為失?。╮ejected)時立即調(diào)用失敗回調(diào)函數(shù)
then: function( doneCallbacks, failCallbacks ) {
// 上下文在這里有切換:雖然done返回的是deferred,但是fail指向failDeferred.done,執(zhí)行fail是上下文變?yōu)閒ailDeferred
// 簡單點說就是:
// 調(diào)用done時向deferred添加回調(diào)函數(shù)doneCallbacks
// 調(diào)用fail時向failDeferred添加回調(diào)函數(shù)failCallbacks
// 因此這行表達式執(zhí)行完后,返回的是failDeferred
deferred.done( doneCallbacks ).fail( failCallbacks );
// 強制返回deferred
return this;
},
// 注冊一個callback函數(shù),無論是resolved或者rejected都會被 調(diào)用。
// 其實,是把傳入的函數(shù)(數(shù)組),同時添加到deferred和failDeferred
// 并沒有像我想象的那樣,存到單獨的函數(shù)數(shù)組中
always: function() {
// done的上下文設置為deferred,fail的上下文設置為this
// done和fail的上下文不一致嗎?一致!在這里this等于deferred
// 但是這里如此設置上下文應該該如何解釋呢?與then的實現(xiàn)有什么不一樣呢?
// fail指向fail指向failDeferred.done,默認上下文是failDeferred,failDeferred的回調(diào)函數(shù)數(shù)組callbacks是通過閉包引用的,
// 這里雖然將failDeferred.done方法的上下文設置為deferred,但是不影響failDeferred.done的執(zhí)行,
// 在failDeferred.done的最后將this替換為deferred,實現(xiàn)鏈式調(diào)用,
// 即調(diào)用過程中沒有丟失上下文this,可以繼續(xù)鏈式調(diào)用其他的方法而不會導致this混亂
// 從語法上,always要達到的效果與then要達到的效果一致
// 因此,這行代碼可以改寫為兩行(類似then的實現(xiàn)方式),效果是等價的:
// deferred.done( arguments ).fail( arguments );
// returnr this;
return deferred.done.apply( deferred, arguments ).fail.apply( this, arguments );
},
// 增加失敗回調(diào)函數(shù)
// 狀態(tài)為失?。╮ejected)時立即調(diào)用
fail: failDeferred.done,
// 使用指定的上下文和參數(shù)執(zhí)行失敗回調(diào)函數(shù)隊列
// 通過調(diào)用failDeferred.rejectWith()實現(xiàn)
rejectWith: failDeferred.resolveWith,
// 調(diào)用失敗回調(diào)函數(shù)隊列
// 通過調(diào)用failDeferred.resolve()實現(xiàn)
reject: failDeferred.resolve,
// 判斷狀態(tài)是否為成功(resolved)
isRejected: failDeferred.isResolved,
// 每次調(diào)用回調(diào)函數(shù)之前先調(diào)用傳入的成功過濾函數(shù)或失敗過濾函數(shù),并將過濾函數(shù)的返回值作為回調(diào)函數(shù)的參數(shù)
// 最終返回一個只讀視圖(調(diào)用promise實現(xiàn))
// fnDone在狀態(tài)是否為成功(resolved)時被調(diào)用
// fnFail在狀態(tài)是否為失敗(rejected)時被調(diào)用
// 關于其他的解釋:
// 1. 有的文章翻譯為“管道機制”,從字面無法理解要表達什么含義,因此至少是不準確
// 2. 錯誤理解:所謂的pipe,只是把傳入的fnDone和fnFail放到了成功隊列和失敗隊列的數(shù)組頭部
pipe: function( fnDone, fnFail ) {
return jQuery.Deferred(function( newDefer ) {
jQuery.each( {
done: [ fnDone, "resolve" ], // done在后文中會指向deferred.done
fail: [ fnFail, "reject" ]
}, function( handler, data ) {
var fn = data[ 0 ],
action = data[ 1 ],
returned;
if ( jQuery.isFunction( fn ) ) {
deferred[ handler ](function() {
returned = fn.apply( this, arguments );
if ( returned && jQuery.isFunction( returned.promise ) ) {
returned.promise().then( newDefer.resolve, newDefer.reject );
} else {
newDefer[ action ]( returned );
}
});
} else {
deferred[ handler ]( newDefer[ action ] );
}
});
}).promise();
},
// Get a promise for this deferred
// If obj is provided, the promise aspect is added to the object
// 返回的是一個不完整的Deferred的接口,沒有resolve和reject,即不能 修改Deferred對象的狀態(tài),
// 這是為了不讓外部函數(shù)提早觸發(fā)回調(diào)函數(shù),可以看作是一種只讀視圖。
//
// 比如$.ajax在1.5版本后不再返回XMLHttpRequest,而是返回一個封裝了 XMLHttpRequest和Deferred對象接口的object。
// 其中Deferred部分就是promise()得到 的,這樣不讓外部函數(shù)調(diào)用resolve和reject,防止在ajax完成前觸發(fā)回調(diào)函數(shù)。
// 把這兩個函數(shù)的調(diào)用權限保留給ajax內(nèi)部。
promise: function( obj ) {
if ( obj == null ) {
// 實際只會執(zhí)行一次promise,第一次執(zhí)行的結(jié)果被存儲在promise變量中
if ( promise ) {
return promise;
}
promise = obj = {};
}
var i = promiseMethods.length;
// 又一種循環(huán)遍歷方式
// 我習慣用:
// for( i = 0; i < len; i++ ) 或 for( i = len-1; i >=0; i-- ) 或 for( i = len; i--; )
// jQuery真是遍地是寶!
while( i-- ) {
obj[ promiseMethods[i] ] = deferred[ promiseMethods[i] ];
}
return obj;
}
});
// Make sure only one callback list will be used
// 成功隊列執(zhí)行完成后,會執(zhí)行失敗帶列的取消方法
// 失敗隊列執(zhí)行完成后,會執(zhí)行成功隊列的取消方法
// 確保只有一個函數(shù)隊列會被執(zhí)行,即要么執(zhí)行成功隊列,要么執(zhí)行失敗隊列;
// 即狀態(tài)只能是或成功、或失敗,無交叉調(diào)用
// deferred和failDeferred的canceled屬性,只能通過閉包引用,因此不用擔心狀態(tài)、上下文的混亂
deferred.done( failDeferred.cancel ).fail( deferred.cancel );
// Unexpose cancel
// 隱藏cancel接口,即無法從外部取消成功函數(shù)隊列
delete deferred.cancel;
// Call given func if any
// 執(zhí)行傳入的func函數(shù)
if ( func ) {
func.call( deferred, deferred );
}
return deferred;
}

5.5 jQuery.when
復制代碼 代碼如下:

// Deferred helper
// 異步隊列工具函數(shù)
// firstParam:一個或多個Deferred對象或JavaScript普通對象
when: function( firstParam ) {
var args = arguments,
i = 0,
length = args.length,
count = length,
// 如果arguments.length等于1,并且firstParam是Deferred,則deferred=firstParam
// 否則創(chuàng)建一個新的Deferred對象(如果arguments.length等于0或大于1,則創(chuàng)建一個新的Deferred對象)
// 通過jQuery.isFunction( firstParam.promise )簡單的判斷是否是Deferred對象
deferred = length <= 1 && firstParam && jQuery.isFunction( firstParam.promise ) ?
firstParam :
jQuery.Deferred();
// 構造成功(resolve)回調(diào)函數(shù)
function resolveFunc( i ) {
return function( value ) {
// 如果傳入的參數(shù)大于一個,則將傳入的參數(shù)轉(zhuǎn)換為真正的數(shù)組(arguments沒有slice方法,借雞生蛋)
args[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value;
if ( !( --count ) ) {
// Strange bug in FF4:
// Values changed onto the arguments object sometimes end up as undefined values
// outside the $.when method. Cloning the object into a fresh array solves the issue
// 執(zhí)行成功回調(diào)函數(shù)隊列,上下文強制為傳入的第一個Deferred對象
deferred.resolveWith( deferred, sliceDeferred.call( args, 0 ) );
}
};
}
// 如果參數(shù)多于一個
if ( length > 1 ) {
for( ; i < length; i++ ) {
// 簡單的判斷是否是Deferred對象,是則調(diào)用.promise().then(),否則忽略
if ( args[ i ] && jQuery.isFunction( args[ i ].promise ) ) {
// 增加成功回調(diào)函數(shù)和失敗回調(diào)函數(shù)到各自的隊列中
args[ i ].promise().then( resolveFunc(i), deferred.reject );
} else {
// 計數(shù)器,表示發(fā)現(xiàn)不是Deferred對象,而是普通JavaScript對象
--count;
}
}
// 計數(shù)器為0時,表示傳入的參數(shù)都不是Deferred對象
// 執(zhí)行成功回調(diào)函數(shù)隊列,上下文強制為傳入的第一個Deferred對象
if ( !count ) {
deferred.resolveWith( deferred, args );
}
// deferred !== firstParam,即deferred為新創(chuàng)建的Deferred對象
// 即length == 0
} else if ( deferred !== firstParam ) {
// 執(zhí)行成功回調(diào)函數(shù)隊列,上下文強制為新創(chuàng)建的Deferred對象
deferred.resolveWith( deferred, length ? [ firstParam ] : [] );
}
// 返回傳入的第一個Deferred或新創(chuàng)建的Deferred對象的只讀視圖
return deferred.promise();
}


5.6 Deferred應用
l jQuery.ajax()
n TODO
5.7 可以學習的技巧
l 閉包
復制代碼 代碼如下:

function a(){
var guid = 1;
return function(){
return guid++;
}
}
var defer = a();
console.info( defer() ); // 1
console.info( defer() ); // 2
console.info( defer() ); // 3
console.info( defer() ); // 4

l 避免null、undefined造成ReferenceError的常見技巧
args = args || [];
l 遍歷動態(tài)數(shù)組的技巧
while( callbacks[ 0 ] ) {
callbacks.shift().apply( context, args );
}
l try/catch/finally 實現(xiàn)錯誤處理
語法
說明
try {
// tryStatements
} catch( exception ) {
// catchStatements
} finally {
// finallyStatements
}
tryStatements
必選項。
可能發(fā)生錯誤的語句。
exception
必選項。任何變量名。
exception 的初始化值是扔出的錯誤的值。
catchStatements
可選項。
處理在相關聯(lián)的 tryStatement 中發(fā)生的錯誤的語句。
finallyStatements
可選項。
在所有其他過程發(fā)生之后無條件執(zhí)行的語句。
l 鏈式對象:通過返回this實現(xiàn)鏈式調(diào)用
方法
返回值
done
this(即deferred)
resolveWith
this(即deferred)
resolve
this(即deferred)
cancel
this(即deferred)
l 代碼復用 $.each
jQuery.each( {
done: [ fnDone, "resolve" ], // done在后文中會指向deferred.done
fail: [ fnFail, "reject" ]
}, function( handler, data ) {
// 公共代碼復用
});
5.8 后續(xù)
l Deferred在jQuery中的應用
l Deferred的自定義應用

相關文章

  • jQuery實現(xiàn)漂亮實用的商品圖片tips提示框效果(無圖片箭頭+陰影)

    jQuery實現(xiàn)漂亮實用的商品圖片tips提示框效果(無圖片箭頭+陰影)

    這篇文章主要介紹了jQuery實現(xiàn)漂亮實用的商品圖片tips提示框效果,具有鼠標滑過顯示動態(tài)提示框的效果,涉及針對鼠標事件的響應及頁面元素動態(tài)操作技巧,需要的朋友可以參考下
    2016-04-04
  • 基于jquery封裝的一個js分頁

    基于jquery封裝的一個js分頁

    基于jquery封裝的一個js分頁代碼,需要的朋友可以參考下。
    2011-11-11
  • JQuery 在線引用及測試引用是否成功

    JQuery 在線引用及測試引用是否成功

    這篇文章主要介紹了JQuery 在線引用及測試引用是否成功的示例,需要的朋友可以參考下
    2014-06-06
  • jQuery 浮動廣告實現(xiàn)代碼

    jQuery 浮動廣告實現(xiàn)代碼

    用jquery實現(xiàn)的浮動廣告代碼,需要的朋友可以參考下。
    2008-12-12
  • jQuery事件與動畫超詳細講解

    jQuery事件與動畫超詳細講解

    在jquery中,jquery動畫事件和動畫函數(shù)經(jīng)常用的到,今天小編抽時間給大家整理了些關于常用的jquery動畫事件和動畫函數(shù),對jquery動畫函數(shù)和動畫事件相關知識感興趣的朋友一起學習吧
    2022-12-12
  • JQuery 的跨域方法推薦_可跨任何網(wǎng)站

    JQuery 的跨域方法推薦_可跨任何網(wǎng)站

    下面小編就為大家?guī)硪黄狫Query 的跨域方法推薦_可跨任何網(wǎng)站。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-05-05
  • 改善用戶體驗的五款jQuery插件分享

    改善用戶體驗的五款jQuery插件分享

    改善網(wǎng)頁的用戶體驗,可以從以下幾個方面入手:菜單欄,tab,登錄/注冊,搜索,以及404頁面。對于每一方面的優(yōu)化,Gevin分別向大家推薦一個自己私藏的jquery插件,希望對大家有幫助,也歡迎大家多多交流
    2011-05-05
  • jQuery Validation Plugin驗證插件手動驗證

    jQuery Validation Plugin驗證插件手動驗證

    jquery.validate是jquery旗下的一個驗證框架,借助jquery的優(yōu)勢,我們可以迅速驗證一些常見的輸入,并且可以自己擴充自己的驗證方法,并且對國際化也有很好的支持,接下來通過本文給大家介紹jQuery Validation Plugin驗證插件手動驗證
    2016-01-01
  • jQuery 插件實現(xiàn)隨機自由彈跳氣泡樣式

    jQuery 插件實現(xiàn)隨機自由彈跳氣泡樣式

    一個基于jQuery的氣泡動畫插件,在指定區(qū)域上方(左/右)定時間隔產(chǎn)生氣泡,然后隨機水平速度進行仿自由落體運動。這篇文章主要介紹了jQuery 插件實現(xiàn)隨機自由彈跳氣泡樣式的相關資料,需要的朋友可以參考下
    2017-01-01
  • jQuery中isFunction方法的BUG修復

    jQuery中isFunction方法的BUG修復

    修復 jQuery 中 isFunction 方法的 BUG
    2010-01-01

最新評論

沙河市| 丹棱县| 耒阳市| 什邡市| 安溪县| 石柱| 广水市| 遵义市| 会宁县| 加查县| 东阿县| 怀柔区| 平罗县| 扎囊县| 巩义市| 大洼县| 库尔勒市| 平湖市| 资中县| 子洲县| 通州市| 高邑县| 黑河市| 武冈市| 禄丰县| 丘北县| 禄丰县| 黎川县| 盐津县| 宜兴市| 北京市| 磐石市| 绥阳县| 武鸣县| 浑源县| 微博| 板桥市| 桐梓县| 古蔺县| 昌江| 南昌市|