本文從同步/非同步原理角度出發,介紹了App的優化方法,靈活使用這些方法,可以在開發App時給使用者帶來更好的使用體驗。
標準的JavaScript的執行分為同步和非同步兩種模式,APICloud的所有擴充套件API也同樣支援同步或非同步的呼叫,它們適用於不同的場景。
在瀏覽器引擎中,JavaScript引擎是單執行緒執行的,單執行緒意味著在同一時間內只能有一段程式碼被JavaScript引擎執行。所以JavaScript函式以一個接一個的棧方式執行,A函式如果依賴B函式的返回結果,那麼A函式必須同步等待B函式返回的結果後才有執行機會。
JavaScript的同步模式符合開發人員通常的編碼習慣,但效能問題也因此而起,當函式棧中某個函式的執行耗費時間過長時,將引起函式棧中後邊的所有函式延遲執行,引發程式效能問題。這在移動端體驗場景優先的場景下是無法接受的。
非同步模式因此誕生。APICloud所有的擴充套件API在現有的JavaScript同步模式的基礎上,引入了JavaScript CMD (Common Module Definition) 的模組化定義規範,API的呼叫遵循AMD(Asynchronous Module Definition)的非同步方式載入,通過實現AMD規範下的JavaScript 非同步載入模式,能夠很好地解決效能問題。
APICloud的JavaScript非同步程式設計模式可以總結為三個關鍵詞:回撥函式、事件監聽和require。典型的程式碼使用如下:
<script>
function readFile(){
var fs = api.require('fs');
fs.read({
fd:'fileId'
},printFile);
console.log('readFile執行完畢....');
}
//回撥函式
function printFile(ret,err){
if(ret.status){
var text = ret.data;
console.log('printFile內容:'+ text);
}else{
console.log(JSON.stringify(err));
}
}
</script>
當呼叫fs模組的read函式時,將進入對應原生Android和ios系統層操作,將在原生子執行緒中執行檔案讀取的操作。操作結束後,將回撥JavaScript。這樣做的好處在於,App不會因為讀取檔案大小,耗時不同而引起阻塞,如果此時裝置正在進行UI渲染,將產生“卡頓”的問題,以上程式碼日誌輸出順序為:
console.log('readFile執行完畢....');
//若干時長後,因檔案大小而花費時長不一
console.log('printFile內容:'+ text);
非同步的模式能夠讓App的邏輯功能與UI渲染很好地解耦,將耗時的操作放在多執行緒裡執行,充分利用裝置的硬體效能,使App更專注於渲染,提供更好的視覺效果及響應速度給使用者。
在APP開發過程中,可以根據不同的操作場景,合理地將同步操作與非同步操作相結合,編寫出結構更合理、效能更出色、維護更方便的JavaScript程式碼。
APICloud擴充套件的API中,支援同步操作的api物件介面通過傳入sync引數進行同步操作宣告;支援同步操作的模組介面以Sync結尾。
(1) 使用同步的介面獲取App快取大小,相關API呼叫方法的程式碼如下:
//同步呼叫
function sycacheSize() {
var size = api.getCacheSize({
sync: true
});
alert('快取大小為:' + size + '位元組');
}
//非同步呼叫
function aycacheSize() {
api.getCacheSize(function (ret) {
var size = ret.size;
alert('快取大小為:' + size + '位元組');
});
}
(2)使用同步介面判斷偏好設定,程式碼如下
//同步呼叫
function isLoginSyc() {
var Login = api.getPrefs({
sync: true,
key: 'is_login'
});
alert('登入狀態:' + login);
}
//非同步呼叫
function isLoginAyc() {
api.getPrefs({
key: 'is_login'
}, isLoginCallback);
}
function isLoginCallback(ret) {
var login = ret.value;
alert('登入狀態:' + login);
}