在之前,我寫了一個websql的封裝類庫,代碼如下: (function(win) { function smpWebSql(options){ options = options || {}; this.database = null; this.DateBaseName = options.Da ...
在之前,我寫了一個websql的封裝類庫,代碼如下:
(function(win) { function smpWebSql(options){ options = options || {}; this.database = null; this.DateBaseName = options.DateBaseName || 'SmpDB'; this.Version = options.Version || '1.0'; this.Description = options.Description || 'SmpDB'; this.DataBaseSize = options.DataBaseSize || 2 * 1024 * 1024; this.init(); } smpWebSql.prototype = { init: function() { this.database = openDatabase(this.DateBaseName, this.Version, this.Description, this.DataBaseSize); //初始化資料庫 }, addBlob: function (tableName, arr,index,isFirst,callback) {//批量添加欄位 /* 註 : 數據裡面的第一個key存儲類型為BLOB @param tableName 表名 @param arr 更新的數據 [{key1:value1 , key2 : value2 ...},{key1:value1 , key2 : value2 ...}] @param index BLOG欄位所在的索引位置 @param isFirst 是否是第一次創建表 @param callback 回調 */ if (arr == null) { return this; } callback = this.isFunction(callback) ? callback : new Function(); var _me = this, _db = this.database, keyC = [], keyI = [], _key = ''; arr = arr || []; if (arr && arr.constructor == Array) { for (var i in arr[0]) { keyC.push(i); keyI.push(i); } _key = keyI.join(","); index = index == undefined ? 0 : index; keyC[index] = keyC[index] + ' BLOB'; _db.transaction(function (tx, result) { //var csql = 'CREATE TABLE IF NOT EXISTS ' + tableName + ' (' + keyC.join(",") + ')'; //console.log('csql:' + csql); if (isFirst == true) { tx.executeSql('CREATE TABLE IF NOT EXISTS ' + tableName + ' (' + keyC.join(",") + ')'); } //var sql = ""; for (var s = 0, _len = arr.length; s < _len ; s++) { var _value = _me.split(arr[s]); //sql += 'INSERT INTO ' + tableName + ' (' + _key + ') VALUES (' + _value + ')'; //console.log("sql:" + sql); tx.executeSql('INSERT INTO ' + tableName + ' (' + _key + ') VALUES (' + _value + ')',[],function (tx, result) { callback(result.rowsAffected); //console.log('添加成功'+result.rowsAffected); },function (tx, error) { console.error('添加失敗'); callback(false); }); } _key = keyI = keyC = null; callback(); }); } return this; }, add: function (tableName, arr, callback, noKey) {//批量添加欄位 /* 註 : 數據裡面的第一個key 為主鍵 @param tableName 表名 @param arr 更新的數據 [{key1:value1 , key2 : value2 ...},{key1:value1 , key2 : value2 ...}] @param callback 回調 @param noKey 第一個欄位是否是主鍵(預設是) */ if(arr==null){ return this; } callback = this.isFunction(callback) ? callback : new Function(); var _me = this, _db = this.database, keyC = [], keyI = [], _key = ''; arr = arr || []; if (arr && arr.constructor == Array) { for(var i in arr[0]){ keyC.push(i); keyI.push(i); } if (noKey==undefined) { keyC[0] = keyC[0] + ' unique'; } _key = keyI.join(","); _db.transaction(function (tx) { ///var csql = 'CREATE TABLE IF NOT EXISTS ' + tableName + ' (' + keyC.join(",") + ')'; // console.log('csql:' + csql); tx.executeSql('CREATE TABLE IF NOT EXISTS ' + tableName + ' (' + keyC.join(",") + ')'); //var sql = ""; for(var s = 0 , _len = arr.length; s < _len ; s++){ var _value = _me.split(arr[s]); //sql += 'INSERT INTO ' + tableName + ' (' + _key + ') VALUES (' + _value + ')'; //console.log("sql:" + sql); tx.executeSql('INSERT INTO '+tableName+' ('+_key+') VALUES ('+_value+')',[],function (tx, result) { callback(result.rowsAffected); //console.log('添加成功'+result.rowsAffected); },function (tx, error) { console.error('添加失敗'); callback(false); }); } _key = keyI = keyC = null; callback(); }); } return this; }, update : function(tableName,key,value,obj,callback){//更新指定數據 /* @param tableName 表名 @param key 查詢的鍵 @param value 對應鍵的值 @param obj 更新的數據 {key1:value1 , key2 : value2 ...} @param callback 回調 傳遞參數為真則查詢成功 反之更新失敗 */ callback = this.isFunction(callback) ? callback : new Function(); var _db = this.database, _value = this.splitU(obj); _db.transaction(function (tx) { //console.log('sql:' + 'UPDATE ' + tableName + ' set ' + _value + ' where ' + key + '="' + value + '"') tx.executeSql('UPDATE '+tableName+' set '+_value+' where '+key+'="'+value+'"',[],function (tx, result) { callback(result.rowsAffected); },function (tx, error) { console.error('更新失敗'); callback(false); }); }); return this; }, updateWhere: function (tableName, where, obj, callback) {//更新指定數據 /* @param tableName 表名 @param 查詢條件 @param obj 更新的數據 {key1:value1 , key2 : value2 ...} @param callback 回調 傳遞參數為真則查詢成功 反之更新失敗 */ callback = this.isFunction(callback) ? callback : new Function(); var _db = this.database, _value = this.splitU(obj); _db.transaction(function (tx) { console.log('UPDATE ' + tableName + ' set ' + _value + ' where ' + where + '"') tx.executeSql('UPDATE ' + tableName + ' set ' + _value + ' where ' + where + '"', [], function (tx, result) { callback(result.rowsAffected); }, function (tx, error) { console.error('更新失敗'); callback(false); }); }); return this; }, read : function(tableName,condition,callback){ //讀取表數據 /* @param tableName 表名 @param condition 查詢條件 'where name="汪文君"' @param callback 回調 傳遞參數為真則查詢成功 反之查詢失敗 */ var _condition = this.isString(condition) ? condition : ''; var _callback = this.isFunction(condition) ? condition : this.isFunction(callback) ? callback : new Function; var _db = this.database, _me = this, _re = []; _db.transaction(function (tx) { tx.executeSql('SELECT * FROM ' + tableName + ' ' + _condition + ' ', [], function (tx, results) { if(results && results.rows){ _re =_me.toArray(results.rows); _callback(_re); }else{ _callback([]); } },function(tx,error){ _callback([]); console.error('查詢失敗'); }); }); return this; }, remove:function(tableName,condition,callback){//刪除數據 /* @param tableName 表名 @param condition 查詢條件 'where name="汪文君"' @param callback 回調 傳遞參數為真則刪除成功 反之刪除失敗 */ var _me = this; var _condition = this.isString(condition) ? condition : ''; var _callback = this.isFunction(condition) ? condition : this.isFunction(callback) ? callback : new Function; _me.database.transaction(function (tx) { tx.executeSql('DELETE FROM '+tableName+ ' '+ _condition+' ',[],function (tx, result) { _callback(result.rowsAffected); },function (tx, error) { _callback(false); console.error('刪除失敗'); }); }); }, counts: function (tableName, condition, callback) { //讀取表數據 /* @param tableName 表名 @param condition 查詢條件 'where name="汪文君"' @param callback 回調 傳遞參數為真則查詢成功 反之查詢失敗 */ var _condition = this.isString(condition) ? condition : ''; var _callback = this.isFunction(condition) ? condition : this.isFunction(callback) ? callback : new Function; var _db = this.database, _me = this, _re = []; if (mui.os.ios) { //ios下麵特有的 _db.transaction(function (tx) { tx.executeSql('SELECT NO FROM ' + tableName + ' ' + _condition + ' ', [], function (tx, results) {// count (*) as num if (results && results.rows) { _re = _me.toArray(results.rows); _callback(_re.length); } else { _callback(0); } }, function (tx, error) { _callback(0); console.error('查詢失敗'); }); }); } else { _db.transaction(function (tx) { tx.executeSql('SELECT count (*) as num FROM ' + tableName + ' ' + _condition + ' ', [], function (tx, results) {// count (*) as num if (results && results.rows) { if (results.rows[0]) { _callback(results.rows[0].num); } else { _callback(0); } } else { _callback(0); } }, function (tx, error) { _callback(0); console.error('查詢失敗'); }); }); } return this; }, delTable:function(tableName,callback){ //刪除數據表 callback = this.isFunction(callback) ? callback : new Function(); this.database.transaction(function(tx){ tx.executeSql('DROP TABLE IF EXISTS '+tableName,[],function(tx,res){ callback(); },function(tx,err){ console.error(err); }); }); return this; }, splitU: function(obj){//更新字元處理 var _arr = []; for(var t in obj){ _arr.push(t+'="'+obj[t]+'"'); } return _arr.join(','); }, split : function(obj){//添加字元處理 var _arr = []; for(var m in obj){ _arr.push("'"+obj[m]+"'"); } return _arr.join(','); }, isFunction : function(callback){ return typeof callback != 'undefined' && callback.constructor == Function ? true : false }, isString : function(string){ return typeof string == 'string' ? true : false }, toArray : function(obj){ var _arr = [], _len = obj.length; if(_len > 0){ for (var i = 0; i < _len; i++) { _arr.push(obj.item(i)); }; } return _arr; } } win.smpWebSql = smpWebSql; }(window))View Code
上述代碼存在的問題非常明顯,由於websql操作都是非同步操作,當我們為了獲取到websql操作的結果之後再進行後續操作時,往往是通過回調函數來實現的,當回調一多的時候,回調地獄就出現了,為瞭解決回調地獄問題,我將通過Promise來改寫,後續調用時,可以直接通過await和async來調用,或者直接通過Promise鏈式調用也是可以的。
現在我將通過ES6的語法重寫之前的封裝類,為了應用ES6中js面向對象的思想,我這裡用到了class,最終代碼如下:
import utils from '@/utils/utils.js'; class SmpWebSql { constructor(options) { options = options || {}; this.database = null; this.DateBaseName = options.DateBaseName || 'RedDB'; this.Version = options.Version || '1.0'; this.Description = options.Description || '智維離線工單資料庫'; this.DataBaseSize = options.DataBaseSize || 2 * 1024 * 1024; this.init(); } /** * 初始化資料庫 */ init() { this.database = openDatabase( this.DateBaseName, this.Version, this.Description, this.DataBaseSize ); } /** * 批量添加欄位 * @param {*} tableName 表名 * @param {*} arr 更新的數據 [{key1:value1 , key2 : value2 ...},{key1:value1 , key2 : value2 ...}] * @param {*} index BLOG欄位所在的索引位置 * @param {*} isFirst 是否是第一次創建表 */ addBlob(tableName, arr, index, isFirst) { var _db = this.database; var _me = this; // eslint-disable-next-line promise/param-names return new Promise(function(resovle, reject) { if (arr == null) { return this; } var keyC = []; var keyI = []; var _key = ''; arr = arr || []; if (arr && arr.constructor == Array) { for (var i in arr[0]) { keyC.push(i); keyI.push(i); } _key = keyI.join(','); index = index == undefined ? 0 : index; keyC[index] = keyC[index] + ' BLOB'; // eslint-disable-next-line promise/param-names _db.transaction(function(tx, result) { // var csql = 'CREATE TABLE IF NOT EXISTS ' + tableName + ' (' + keyC.join(",") + ')'; // console.log('csql:' + csql); if (isFirst == true) { tx.executeSql( 'CREATE TABLE IF NOT EXISTS ' + tableName + ' (' + keyC.join(',') + ')' ); } // var sql = ""; for (var s = 0, _len = arr.length; s < _len; s++) { var _value = _me.split(arr[s]); // sql += 'INSERT INTO ' + tableName + ' (' + _key + ') VALUES (' + _value + ')'; // console.log("sql:" + sql); tx.executeSql( 'INSERT INTO ' + tableName + ' (' + _key + ') VALUES (' + _value + ')', [], function(tx, result) { resovle(result.rowsAffected); // console.log('添加成功'+result.rowsAffected); }, function(tx) { console.error('添加失敗'); // eslint-disable-next-line prefer-promise-reject-errors reject(false); } ); } _key = keyI = keyC = null; resovle(); }); } }); } /** * 批量添加欄位 註 : 數據裡面的第一個key 為主鍵 * @param {*} tableName 表名 * @param {*} arr arr 更新的數據 [{key1:value1 , key2 : value2 ...},{key1:value1 , key2 : value2 ...}] * @param {*} noKey noKey 第一個欄位是否是主鍵(預設是) */ add(tableName, arr, noKey) { var _me = this; var _db = this.database; // eslint-disable-next-line promise/param-names return new Promise(function(resovle, reject) { if (arr == null) { return this; } var keyC = []; var keyI = []; var _key = ''; arr = arr || []; if (arr && arr.constructor == Array) { for (var i in arr[0]) { keyC.push(i); keyI.push(i); } if (noKey == undefined) { keyC[0] = keyC[0] + ' unique'; } _key = keyI.join(','); _db.transaction(function(tx) { // /var csql = 'CREATE TABLE IF NOT EXISTS ' + tableName + ' (' + keyC.join(",") + ')'; // console.log('csql:' + csql); tx.executeSql( 'CREATE TABLE IF NOT EXISTS ' + tableName + ' (' + keyC.join(',') + ')' ); // var sql = ""; for (var s = 0, _len = arr.length; s < _len; s++) { var _value = _me.split(arr[s]); // sql += 'INSERT INTO ' + tableName + ' (' + _key + ') VALUES (' + _value + ')'; // console.log("sql:" + sql); tx.executeSql( 'INSERT INTO ' + tableName + ' (' + _key + ') VALUES (' + _value + ')', [], function(tx, result) { resovle(result.rowsAffected); // console.log('添加成功'+result.rowsAffected); }, function(tx, error) { console.error('添加失敗'); // eslint-disable-next-line prefer-promise-reject-errors reject(false); } ); } _key = keyI = keyC = null; // resovle(); }); } }); } /** * 更新指定數據 * @param {*} tableName 表名 * @param {*} key 查詢的鍵 * @param {*} value 對應鍵的值 * @param {*} obj obj 更新的數據 {key1:value1 , key2 : value2 ...} */ update(tableName, key, value, obj) { var _db = this.database; var _value = this.splitU(obj); // eslint-disable-next-line promise/param-names return new Promise(function(resovle, reject) { _db.transaction(function(tx) { // console.log('sql:' + 'UPDATE ' + tableName + ' set ' + _value + ' where ' + key + '="' + value + '"') tx.executeSql( 'UPDATE ' + tableName + ' set ' + _value + ' where ' + key + '="' + value + '"', [], function(tx, result) { resovle(result.rowsAffected); }, function(tx, error) { console.error('更新失敗'); // eslint-disable-next-line prefer-promise-reject-errors reject(false); } ); }); }); } /** * 更新指定數據 * @param {*} tableName 表名 * @param {*} where 查詢條件 * @param {*} obj obj 更新的數據 {key1:value1 , key2 : value2 ...} */ updateWhere(tableName, where, obj) { var _db = this.database; var _value = this.splitU(obj); // eslint-disable-next-line promise/param-names return new Promise(function(resovle, reject) { _db.transaction(function(tx) { console.log( 'UPDATE ' + tableName + ' set ' + _value + ' where ' + where + '"' ); tx.executeSql( 'UPDATE ' + tableName + ' set ' + _value + ' where ' + where + '"', [], function(tx, result) { resovle(result.rowsAffected); }, function(tx, error) { console.error('更新失敗'); // eslint-disable-next-line prefer-promise-reject-errors reject(false); } ); }); }); } /** * 讀取表數據 * @param {*} tableName 表名 * @param {*} condition 查詢條件 'where name="jiekzou"' */ read(tableName, condition) { var _db = this.database; var _me = this; // eslint-disable-next-line promise/param-names return new Promise(function(resovle, reject) { var _condition = this.isString(condition) ? condition : ''; var _re = []; _db.transaction(function(tx) { tx.executeSql( 'SELECT * FROM ' + tableName + ' ' + _condition + ' ', [], function(tx, results) { if (results && results.rows) { _re = _me.toArray(results.rows); resovle(_re); } else { resovle([]); } }, function(tx, error) { // eslint-disable-next-line prefer-promise-reject-errors reject([]); console.error('查詢失敗'); } ); }); }); } /** * 刪除數據 * @param {*} tableName 表名 * @param {*} condition 查詢條件 'where name="jiekzou"' */ remove(tableName, condition) { var _me = this; var _condition = this.isString(condition) ? condition : ''; // eslint-disable-next-line promise/param-names return new Promise(function(resovle, reject) { _me.database.transaction(function(tx) { tx.executeSql( 'DELETE FROM ' + tableName + ' ' + _condition + ' ', [], function(tx, result) { resovle(result.rowsAffected); }, function(tx, error) { // eslint-disable-next-line prefer-promise-reject-errors reject(false); console.error('刪除失敗'); } ); }); }); } /** * 根據查詢條件讀取表記錄數 * @param {*} tableName 表名 * @param {*} condition 查詢條件 'where name="jiekzou"' */ counts(tableName, condition) { if (utils.browserVersions.android) { return this.androidCounts(tableName, condition); } else { return this.iosCounts(tableName, condition); } } // ios下麵特有的 /** * 讀取表數據(ios下麵特有的) * @param {*} tableName 表名 * @param {*} condition 查詢條件 'where name="jiekzou"' */ iosCounts(tableName, condition) { var _condition = this.isString(condition) ? condition : ''; var _db = this.database; var _me = this; // eslint-disable-next-line promise/param-names return new Promise(function(resovle, reject) { var _re = []; _db.transaction(function(tx) { tx.executeSql( 'SELECT NO FROM ' + tableName + ' ' + _condition + ' ', [], function(tx, results) { // count (*) as num if (results && results.rows) { _re = _me.toArray(results.rows); resovle(_re.length); } else { resovle(0); } }, function(tx, error) { // eslint-disable-next-line prefer-promise-reject-errors reject(0); console.error('查詢失敗'); } ); }); }); } /** * 讀取表數據(Android) * @param {*} tableName 表名 * @param {*} condition 查詢條件 'where name="jiekzou"' */ androidCounts(tableName, condition) { var _condition = this.isString(condition) ? condition : ''; var _db = this.database; var _me = this; // eslint-disable-next-line promise/param-names return new Promise(function(resovle, reject) { var _re = []; _db.transaction(function(tx) { tx.executeSql( 'SELECT count (*) as num FROM ' + tableName + ' ' + _condition + ' ', [], function(tx, results) { // count (*) as num if (results && results.rows) { if (results.rows[0]) { resovle(results.rows[0].num); } else { resovle(0); } } else { resovle(0); } }, function(tx, error) { // eslint-disable-next-line prefer-promise-reject-errors reject(0); console.error('查詢失敗'); } ); }); }); } /** * 刪除數據表 * @param {*} tableName 表名 */ delTable(tableName) { // eslint-disable-next-line promise/param-names return new Promise(function(resovle, reject) { this.database.transaction(function(tx) { tx.executeSql( 'DROP TABLE IF EXISTS ' + tableName, [], function(tx, res) { resovle(); }, function(tx, err) { console.error(err); // eslint-disable-next-line prefer-promise-reject-errors reject(0); } ); }); }); } // 更新字元處理 splitU(obj) { var _arr = []; for (var t in obj) { _arr.push(t + '="' + obj[t] + '"'); } return _arr.join(','); } // 添加字元處理 split(obj) { var _arr = []; for (var m in obj) { _arr.push('\'' + obj[m] + '\''); } return _arr.join(','); } isFunction(callback) { return !!( typeof callback != 'undefined' && callback.constructor == Function ); } isString(string) { return typeof string == 'string'; } toArray(obj) { var _arr = []; var _len = obj.length; if (_len > 0) { for (var i = 0; i < _len; i++) { _arr.push(obj.item(i)); } } return _arr; } } export default SmpWebSql;