Basic information of the project
Using uni app development, the client selects sqllite for local data storage
Uni app reference address
Uni app official website (dcloud.io)
sqllite reference address
HTML5+ API Reference (html5plus.org)
Solutions to asynchronous
Asynchronously executed code generally has callbacks. Create your own callback function in the outer method to realize business operations through callbacks and realize the logic of "synchronous execution".
development process
Due to business needs, local data storage is required at the app client. I have been developing java all the year round, and the object-oriented concept is deeply rooted in the hearts of the people, so I need to write a dbutils in the right place JS tool class, which provides methods for database addition, deletion, modification and query, and returns execution results. However, during the debugging process, it is found that the method of sqllite operating the database is asynchronous, so the correct results can not be obtained according to the traditional return value method.
Initial idea: first define the return result variable, and then return the result after the operation is completed
// This method doesn't work! export function executeSql(sql){ let result = false; // Open database plus.sqlite.openDatabase({ // Database name name: 'xxxxx', // Database file path path: '_doc/xxxxx.db', // Database opened successfully success: function(e){ result = true; }, fail:function(e){ console.log(e); } }); if (result) { // Execute sql plus.sqlite.executeSql({ name:'xxxxx', sql: sql, success(){ result = true; }, fail(e) { console.log(e); } }); } // close database plus.sqlite.closeDatabase({name: 'xxxxx'}); return result; }
Through debugging, it is found that the method always returns false when executing plus sqllite. At XXX, js continued to execute without waiting. As a result, the database was closed. Later, I wrote the execution sql in the callback to open the database, and the database was closed in the callback to execute sql. However, it can only solve the problem that the execution sequence of the database operation part is correct, and the return value is still incorrect.
At this time, I want to solve this asynchronous problem violently. I have a naive and bold idea to block the program execution during asynchronous execution and monitor whether the asynchronous operation is completed
let executeFinished = false; ......Various database operations, assignment upon completion executeFinished = true; while(true) { if (executeFinished) { break; } } ......Subsequent operation
Then it is found that the program card is in while(true), and the callback method of database operation will never be accessed. executeFinished will never change.
After consulting the data, it is found that js is single threaded, so the while(true) loop program is blocked. The asynchronous processing in js is only executed at the right time, and the underlying is not parallel.
Finally, the asynchronous problem of sqllite is solved by passing callback events to public methods
Final code
Tool class: dbutils js
/** * Add / delete / modify sql execution * @param {Object} sql * @param {Object} callback */ export function executeSql(sql, callback){ let result = {}; // Open database plus.sqlite.openDatabase({ // Database name name: 'xxxxx', // Database file path path: '_doc/xxxxx.db', // Database opened successfully 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); } }); } /** * Database query select * @param {Object} sql * @param {Object} callback */ export function selectSql(sql, callback){ let result = {}; // Open database plus.sqlite.openDatabase({ // Database name name: 'xxxxx', // Database file path path: '_doc/xxxxx.db', // Database opened successfully 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); } }); } /** * close database */ function closeDatabase() { plus.sqlite.closeDatabase({name: 'xxxxx'}); }
introduce:
import { executeSql } from '@/common/db/dbUtils.js';
Call:
let sql = "insert into xxxxxxxxxx"; executeSql(sql, function(result) { if (result.success) { // Business operation } else { // Failed operation } });