欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

D3.js中強制異步文件讀取同步的幾種方法

 更新時間:2017年02月06日 08:32:42   投稿:daisy  
這篇文章主要給大家介紹了d3.js中強制異步文件讀取同步的幾種方法,文中給出了詳細的介紹和解決方法,對大家具有一定的參考價值,需要的朋友們下面來一起學習學習吧。

發(fā)現(xiàn)問題

在使用d3.js時,我們經(jīng)常會使用d3.csv()或者d3.json()函數(shù)來從文件中讀取出數(shù)據(jù),不幸的是,偶爾代碼的結果并不是我們預料的那樣。習慣了過程式編程的我開始的時候也是這樣,最讓人頭疼的是javascript并不會告訴你問題出在哪里了。我第一次遇到這個問題的時候,找了半天bug,確定代碼主體部分沒有問題之后,我只能開始使用console.log()將變量一個一個的輸出到控制臺里。

第一次遇到這個問題時的圖片是這樣的:


問題出在第72行和第75行,中間幾行完全沒有對ordertxt進行操作,但是最后的結果就是和預想的輸出不吻合,后來找了個其他方法把這個問題給解決了,今天又遇到了類似的這個問題,就下決心來拔掉這根刺。

試驗

\<script\>

console.log("before csv1 ");
d3.csv("flowers.csv", function(data) {console.log(data)});
console.log("before csv2");
d3.csv("flowers.csv",function(error,data2) {console.log(error, data2)});

\</script\>

believe it or not,上面的代碼將產(chǎn)生下面圖中的輸出結果,因為javascript的 異步特性 。說到異步,大部分時候是讓人開心的,但偶爾也會令人頭疼,至少在這里,就是令人頭疼。

解決方法1

第一次遇到這個問題的時候,我巧妙的繞開了這個問題,使用的方法是:我把數(shù)據(jù)的處理放在了d3.csv(“flowers.csv”,function(data){dealWithData()…})回調函數(shù)里面,這樣數(shù)據(jù)的處理就和d3的讀文件操作變成了綁在一根繩上的螞蚱了,要么一起執(zhí)行完,要么都不執(zhí)行。貌似世界和平了,但是今天下午又遇到了這個問題,而且數(shù)據(jù)的變化是隨時隨地的,可不是和上一次遇到的那樣,所有會發(fā)生的變化都可以預先寫成代碼的。于是我開始了對解決方法的苦苦追尋。

解決方法2

第二種方法是借助一些helper類庫(queue.js)來強制數(shù)據(jù)在加載完成之后才去觸發(fā)相應的操作。這種方法是我在網(wǎng)上看到的,并沒有去親自試過,也許會成功,但是對于我們會變化的數(shù)據(jù),不能提前將處理邏輯寫出代碼,這種方法還是不合格的。

解決方法3

第三種方法是在stack overflow里查到的,試了一下是可以的,他這里用的是d3.text()函數(shù),將文件先load進來,然后再使用d3.csv.parse或者d3.csv.parseRows,這樣就會是同步的了。參考文末的Reference 3的實現(xiàn)。

解決方法4

方法4是我自己想出來的,最近幾天一直在做angular和d3結合在一起的工作,我就在想能否借助angular來幫助我們完成呢?萬幸,Angular中確實有這么一個函數(shù),似乎就是為這個問題量身定做的,且解決了前面的方法都沒有解決的數(shù)據(jù)后期動態(tài)變化的問題。這個函數(shù)就是 $watch 函數(shù)。

$watch列表

每當我們在視圖中追蹤一個事件時,會給它注冊一個回調函數(shù),然后希望在頁面中觸發(fā)該事件時調用這個回調函數(shù)。比如AngularJS中最令人印象深刻的雙向綁定,在input中輸入一個字母,有著相同ng-model的變量就會跟著input的輸入而發(fā)生改變。

發(fā)生這一變化的原因是我們把UI中的輸入字段綁定給了$scope.name屬性,為了更新這個視圖,Angular需要 追蹤變化 ,是通過給$watch列表添加一個監(jiān)控函數(shù)做到這一點的。

臟檢查

臟檢查是一個簡單的過程,可歸結為一個非常基礎的概念:檢查值是否發(fā)生了變化,而整個應用還沒同步該變化。Angular會遍歷$watch列表,只要有任何的值發(fā)生比變化,應用將會退回到$watch循環(huán)中,直到檢測到不在發(fā)生任何變化。

$watch

$scope對象上的$watch方法會給Angular事件循環(huán)內的每個$digest調用裝配一個臟檢查,如果在檢測到變化,Angular總是會返回$digest循環(huán)。

$watch函數(shù)本身接受兩個必要參數(shù)和一個可選的參數(shù),第一個參數(shù)是watch的對象,第二個參數(shù)是 回調函數(shù) ,一旦watch的對象變了的時候觸發(fā);可選的參數(shù)是一個bool值,告訴Angular是否檢查 嚴格相等 。

關于回調函數(shù)和嚴格相等,還有一些想說的。

回調函數(shù)

我一直是這么理解回調函數(shù)的,研究生的導師會分配給每個研究生活去干,而他自己也有自己的事情,如果給某個研究生安排的活他做好了,就過來給他說一聲,導師負責匯總,將活寫成論文發(fā)表出去。這其實就是回調函數(shù)工作的原理。當然導師不可能在這邊等著研究生干活,自己什么都不干;或者自己什么都干了,也沒研究生什么事了。

嚴格相等

比如有一個數(shù)組,a=【1,2,3】,后面修改了a【0】=2,在AngularJS看來,這個數(shù)組并沒有發(fā)生變化,因為還是3個變量,而如果從嚴格意義上來說,它已經(jīng)發(fā)生了變化,這就是嚴格相等和相等的不同,在javascript中,也有==和===的區(qū)別。

實現(xiàn)

寫到這里,大家應該知道該怎么做了,即調用$watch函數(shù)來觀測我們需要關注的data,每當發(fā)生變化的時候,就根據(jù)新的data,重新繪制圖標。因此,我們最好將render的過程抽象成一個函數(shù),方便我們后期調用。比如,我們想要觀測data數(shù)組的變化,并且根據(jù)它的變化來重新繪制圖片。那么我們的代碼實現(xiàn)就應該像下面這樣。

scope.$watch("data", function() {
render();
//render函數(shù)是繪制的過程,換成自己的即可。
},true);

Reference

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作能帶來一定的幫助,如果有疑問大家可以留言交流。

相關文章

最新評論