後來在編程過程當中發現用iterator會更加方便。在Array的iteration方法裏面有這麼一個:Array.prototype[@@iterator]()
。用法是`arr[Symbol.iterator](),好比像下面這樣:javascript
var arr = [1,2,3,4,5,6] var eArr = arr[Symbol.iterator]() console.log(eArr)//Array Iterator {} console.log(eArr.next())//Object {value: 1, done: false}
eArr如今再也不具備length屬性,變成了一個iterator,每次調用next()method都會返回"下一個"元素,當超出arr範圍的時候,value會是undefinde,而done屬性則成了true。說實話和判斷i==arr.length-1也沒什麼太大的區別,不過我以爲寫成iterator更加好一點吧。下面的程序是我在mongoose裏面批量存儲數據時候用到的。(看mongoose的文檔,insertMany命令雖然能夠向model(至關於db裏面的collection)插入大量document,然而並不會進行save。save的話果真仍是要一個document一個document的來。若是把save當作是異步操做那仍是得異步與遍歷一塊兒來,因此就有了下面的程序:(順便說一下,我發現批量數據存數據庫的時候,若是不用insertMany+遍歷save,而是用遍歷(insert+save)的話呢,會在mongod後臺報錯topology error)java
MultipleEntryInsertor.prototype.insertAll = function(data){ this.model1.insertMany(this.data,(err,docs)=>{ if(err)console.error(err) var eDocs = docs[Symbol.iterator]() var entry iter.call(this,eDocs) function iter(eDocs){ var entry = eDocs.next() if(!entry.done){ entry.value.save().then(arguments.callee.call(this,eDocs)) }else{ console.log("done"); this.dbList()//完成遍歷之後執行的工做 } } }) }
涉及文件讀取的時候常常須要用到異步callback,最近寫到一個地方遇到了這麼一個問題:數據庫
好比說如今我有一個數組:編程
var src = ["1.txt","2.txt","3.txt"]
如今我想用fs.readFile分別讀取三個文檔,而後把三個文檔的內容通過處理之後,合併成一個json數據輸出。若是是src.forEach(function(e){...})
沒辦法應對異步。json
開始的時候我以爲既然異步涉及回調,那應該就是用遞歸就行了數組
實際上確實是用遞歸就能夠了異步
//好比如今我要把a數組(好比上面的src)進行一個異步的映射操做造成b數組: var src = ["1.txt","2.txt","3.txt"] var b = [] var asyncFunc=function (i,a,b){ fs.readFile(path.join(__dirname,"file",a[i]),'utf-8',(err,data)=>{ //異步完成之後進行的映射操做: b.push(data) if(i==a.length-1){ console.log("done"); console.log(b); //這裏是a數組已經被遍歷完了,這時候對b數組進行想要的操做 }else{ arguments.callee(i+1,a,b) } }) } asyncFunc(0,src,b)
之前遇到相似的問題的時候去stackOverFlow找過答案,不過沒看到合適的(或者當時沒看到能看懂的),今天總算想通了這一塊,趕忙寫下來。async
固然了,這種寫法仍是挺醜的,畢竟映射操做要寫在異步操做的回調函數裏面,不過總算是能用。mongoose
從新調了一下,發現幾點寫下來:函數
fs.readFile(path.join(__dirname,"file",a[i]),'utf-8',(err,data)=>{...
:異步操做這裏的回調函數必定要寫成()=>{...}這樣的形式,若是使用的是function(err,data){...}這樣的形式arguments.callee會指向這個匿名函數。
暫時沒了