ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

uni-app开发sqllite公共方法(h5使用sqllite同步异步问题)

2021-12-14 17:03:16  阅读:476  来源: 互联网

标签:function success 数据库 h5 xxxxx result sql app sqllite


项目基本情况

        使用uni-app开发,客户端本地数据存储选择sqllite

uni-app参考地址

uni-app官网 (dcloud.io)

sqllite参考地址

HTML5+ API Reference (html5plus.org)

解决异步的方法

        异步执行的代码一般都有回调,在外层方法中创建自己的回调函数,通过回调实现业务操作,曲折实现“同步执行”的逻辑。

开发过程

        由于业务需要,在app客户端要进行本地数据存储。本人常年开发java,面向对象理念深入人心,于是需要在合适的位置写一个dbUtils.js的工具类,提供数据库增删改查的方法,返回执行结果。但是在调试过程中发现sqllite操作数据库的方法是异步的,所以按照传统的返回值方式无法取得正确结果。

        初始思路:先定义返回结果变量,操作完成后返回结果

// 此方法行不通!
export function executeSql(sql){
	let result = false;
	// 打开数据库
    plus.sqlite.openDatabase({
    	// 数据库名称
    	name: 'xxxxx',
    	// 数据库文件路径
    	path: '_doc/xxxxx.db',
    	// 打开数据库成功
    	success: function(e){
    		result = true;
    	},
		fail:function(e){
			console.log(e);
		}
    });
	if (result) {
		// 执行sql
		plus.sqlite.executeSql({
			name:'xxxxx',
			sql: sql,
			success(){
				result = true;
			},
			fail(e) {
				console.log(e);
			}
		});
	}
	// 关闭数据库
	plus.sqlite.closeDatabase({name: 'xxxxx'});
	return result;
}

        通过调试发现方法永远返回false,在执行plus.sqllite.xxx时,js继续执行了,没有等待,导致执行是数据库已经关闭,后来我把执行sql写在打开数据库的回调中,关闭数据库写在执行sql的回调中,但只能解决数据库操作部分的执行顺序正确,返回值仍然不对。

        这时我想暴力解决这个异步问题,产生了一个天真大胆的想法,在异步执行时阻断程序执行,监听异步操作是否执行完成

	let executeFinished = false;
	......各种数据库操作,完成时赋值executeFinished = true;
	while(true) {
		if (executeFinished) {
			break;
		}
	}
	......后续操作

        然后发现程序卡在while(true)那里了,永远进不去数据库操作回调方法,executeFinished自然永远不会变。

        经过查阅资料,发现js是单线程的,那么while(true)一直循环程序就阻断了。js中的异步处理只是合适的时机去执行,底层并不是并行的。

        最后,通过给公共方法传回调事件,曲折解决了sqllite的异步问题

最终代码

工具类:dbUtils.js

/**
 * 增/删/改 sql执行
 * @param {Object} sql
 * @param {Object} callback
 */
export function executeSql(sql, callback){
	let result = {};
    // 打开数据库
    plus.sqlite.openDatabase({
    	// 数据库名称
    	name: 'xxxxx',
    	// 数据库文件路径
    	path: '_doc/xxxxx.db',
    	// 打开数据库成功
    	success: function(e){
    		plus.sqlite.executeSql({
    			name:'xxxxx',
    			sql: sql,
    			success(){
    				result.success = true;
					closeDatabase();
					callback(result);
    			},
				fail(e) {
					result.success = false;
					result.data = e;
					closeDatabase();
					callback(result);
				}
    		});
    	},
		fail:function(e){
			result.success = false;
			result.data = e;
			closeDatabase();
			callback(result);
		}
    });
}
/**
 * 数据库查询select
 * @param {Object} sql
 * @param {Object} callback
 */
export function selectSql(sql, callback){
	let result = {};
    // 打开数据库
    plus.sqlite.openDatabase({
    	// 数据库名称
    	name: 'xxxxx',
    	// 数据库文件路径
    	path: '_doc/xxxxx.db',
    	// 打开数据库成功
    	success: function(e){
    		plus.sqlite.selectSql({
    			name:'xxxxx',
    			sql: sql,
    			success(data){
    				result.success = true;
					result.data = data;
					closeDatabase();
					callback(result);
    			},
				fail(e) {
					result.success = false;
					result.data = e;
					closeDatabase();
					callback(result);
				}
    		});
    	},
		fail:function(e){
			result.success = false;
			result.data = e;
			closeDatabase();
			callback(result);
		}
    });
}
/**
 * 关闭数据库
 */
function closeDatabase() {
	plus.sqlite.closeDatabase({name: 'xxxxx'});
}

引入:

import { executeSql } from '@/common/db/dbUtils.js';

调用: 

let sql = "insert into xxxxxxxxxx";
executeSql(sql, function(result) {
	if (result.success) {
		// 业务操作
	} else {
		// 执行失败操作
	}
});

标签:function,success,数据库,h5,xxxxx,result,sql,app,sqllite
来源: https://blog.csdn.net/qq_34731982/article/details/121928843

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有