/先分別定義各個異步任務 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
回調,這樣依次向下,就避免了層層嵌套。