Flutter 中使用Future消除Callback Hell
/先分别定义各个异步任务 Future<String> login(String userName, String pwd){ ... //用户登录 }; Future<String> getUserInfo(String id){ ... //获取用户信息 }; Future saveUserInfo(String userInfo){ ... // 保存用户信息 }; 接下来,执行整个任务流: login("alice","******").then((id){ //登录成功后通过,id获取用户信息 getUserInfo(id).then((userInfo){ //获取用户信息后保存 saveUserInfo(userInfo).then((){ //保存用户信息,接下来执行其它操作 ... }); }); })
可以感受一下,如果业务逻辑中有大量异步依赖的情况,将会出现上面这种在回调里面套回调的情况,过多的嵌套会导致的代码可读性下降以及出错率提高,并且非常难维护,这个问题被形象的称为回调地狱(Callback Hell)。回调地狱问题在之前JavaScript中非常突出,也是JavaScript被吐槽最多的点,但随着ECMAScript6和ECMAScript7标准发布后,这个问题得到了非常好的解决,而解决回调地狱的两大神器正是ECMAScript6引入了Promise
,以及ECMAScript7中引入的async/await
。 而在Dart中几乎是完全平移了JavaScript中的这两者:Future
相当于Promise
,而async/await
连名字都没改。接下来我们看看通过Future
和async/await
如何消除上面示例中的嵌套问题。
login("alice","******").then((id){ return getUserInfo(id); }).then((userInfo){ return saveUserInfo(userInfo); }).then((e){ //执行接下来的操作 }).catchError((e){ //错误处理 print(e); });
正如上文所述, “Future
的所有API的返回值仍然是一个Future
对象,所以可以很方便的进行链式调用” ,如果在then中返回的是一个Future
的话,该future
会执行,执行结束后会触发后面的then
回调,这样依次向下,就避免了层层嵌套。