func (c MapStringString) MapAsyncInterface(cb func(string, string, chan [2]interface{}), maxConcurrency ...int) MapStringInterface {
	var maxConc = lists.DEFAULT_CONC
	if len(maxConcurrency) == 1 {
		maxConc = maxConcurrency[0]
	}
	mapChan := make(chan [2]interface{}, len(c))
	ret := make(map[string]interface{}, len(c))
	if maxConc > 0 {
		sent := 0
		received := 0
		doing := make(chan struct{}, maxConc)
		indexes := c.Indexes()
		for {
			var k string
			var v string
			if len(indexes) > sent {
				k = indexes[sent]
				v = c[k]
			}
			if len(doing) < maxConc && sent < len(c) {
				go cb(k, v, mapChan)
				sent++
				if maxConc > 0 {
					doing <- struct{}{}
				}
			} else {
				intf := <-mapChan
				received++
				if len(intf) > 1 {
					ret[intf[0].(string)] = intf[1]
				} else {
					ret[intf[0].(string)] = ""
				}
				<-doing
				if received == sent {
					close(mapChan)
					return ret
				}
			}
		}
	} else {
		for k, v := range c {
			go cb(k, v, mapChan)
		}
		ct := 0
		for intf := range mapChan {
			ret[intf[0].(string)] = intf[1]
			ct++
			if ct == len(c) {
				close(mapChan)
			}
		}
	}
	return ret
}
MapAsyncInterface method creates a new slice with the results of calling a provided go routine on every element in the calling array.
Runs asynchronously and needs gives a chan []interface{} to return results.
To keep initial order, the first elemt of th []interface{} written to the chan must be the key. The second element muse be a string.
Returns InterfaceSlice.
If you know the result will be of original type, user MapAsync.
@Todo implement max concurrency (in case a lot of requests for example)
package maps
import "github.com/francoispqt/lists"
type MapStringString map[string]string
func (c MapStringString) Contains(s string) bool {
	for _, v := range c {
		if v == s {
			return true
		}
	}
	return false
}
func (c MapStringString) ForEach(cb func(string, string)) {
	for k, v := range c {
		cb(k, v)
	}
}
func (c MapStringString) Map(cb func(string, string) string) MapStringString {
	var ret = make(map[string]string, len(c))
	for k, v := range c {
		ret[k] = cb(k, v)
	}
	return ret
}
func (c MapStringString) MapInterface(cb func(string, string) interface{}) MapStringInterface {
	var ret = make(map[string]interface{}, len(c))
	for k, v := range c {
		ret[k] = cb(k, v)
	}
	return ret
}
func (c MapStringString) MapAsync(cb func(string, string, chan [2]string), maxConcurrency ...int) MapStringString {
	var maxConc = lists.DEFAULT_CONC
	if len(maxConcurrency) == 1 {
		maxConc = maxConcurrency[0]
	}
	mapChan := make(chan [2]string, len(c))
	ret := make(map[string]string, len(c))
	if maxConc > 0 {
		sent := 0
		received := 0
		doing := make(chan struct{}, maxConc)
		indexes := c.Indexes()
		for {
			var k string
			var v string
			if len(indexes) > sent {
				k = indexes[sent]
				v = c[k]
			}
			if len(doing) < maxConc && sent < len(c) {
				go cb(k, v, mapChan)
				sent++
				if maxConc > 0 {
					doing <- struct{}{}
				}
			} else {
				intf := <-mapChan
				received++
				if len(intf) > 1 {
					ret[intf[0]] = intf[1]
				} else {
					ret[intf[0]] = ""
				}
				<-doing
				if received == sent {
					close(mapChan)
					return ret
				}
			}
		}
	} else {
		for k, v := range c {
			go cb(k, v, mapChan)
		}
		ct := 0
		for intf := range mapChan {
			if len(intf) > 1 {
				ret[intf[0]] = intf[1]
			} else {
				ret[intf[0]] = ""
			}
			ct++
			if ct == len(c) {
				close(mapChan)
			}
		}
	}
	return ret
}