add promise support