javascript中實現異步+遍歷

2017年7月20日更新

後來在編程過程當中發現用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會指向這個匿名函數。

  • 暫時沒了

相關文章
相關標籤/搜索