后来在编程过程当中发现用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会指向这个匿名函数。
暂时没了