我对Javascript中的异步代码感到非常糟糕,现在已经停留了一段时间。
我正在使用WebSql并且只是通过数据库初始化步骤,但其中一个循环没有以我期望的方式执行。
XSD
但是指示结束的日志在for循环结束之前执行。如果我尝试验证数据是否已插入,我总是会失败,因为循环尚未完成插入。
Google表示应该使用promises处理异步代码,但我找不到像这样的实例中使用的promise的示例。
非常感谢任何帮助
答案 0 :(得分:1)
将每个回调转换为promise,然后使用Promise.all
const loDataPromises = lo_data.map(({ code, desc }) => {
return new Promise((resolve, reject) => {
trans.executeSql(
"INSERT",
[code, desc],
function(trans, result) {
console.log('success');
resolve();
},
function(error) {
console.log('failed');
reject();
}
);
});
});
Promise.all(loDataPromises)
.then(() => {
console.log('all done');
});

答案 1 :(得分:0)
我还没能在互联网上找到任何明确的代码示例,所以我想在这里发布工作版本作为答案。希望它也有益于某人也试图理解承诺和承诺循环。
经过彻底检修后,我设法让它以一种有意义的方式运作。我已将其更改为作为承诺链执行,然后带有for循环的函数正在使用promise all逻辑。
$(document).ready(function() {
////
// promise chain
////
console.log("BEGIN");
f_initdatabase().then(function(result) {
return f_defaultdata(result.db);
}).then(function(result) {
console.log("END");
}).catch(function(result) {
// abandon all hope
});
});
////
// single promise usage
////
function f_initdatabase() {
return new Promise(function(resolve, reject) {
console.log(" INIT DB");
var lo_result = {db:null};
var lv_db = window.openDatabase("thenothing", "1.0", "The Nothing DB", 2 * 1024 * 1024);
lv_db.transaction(function(trans) {
trans.executeSql ("create table if not exists dummydata (dd_idno integer primary key, dd_code text not null, dd_desc text not null)", [], function(trans, results) {
console.log(" INIT DB : DONE");
lo_result.db = lv_db;
resolve(lo_result);
}, function(error) {
lo_result.db = null;
reject(lo_result);
});
});
});
}
////
// loop promise all usage
////
function f_defaultdata(lv_db) {
return new Promise(function(resolve, reject) {
console.log(" DEF DATA");
var lo_result = {db:null};
lv_db.transaction(function(trans) {
var la_promises = [];
var lo_data = [
{dd_code:"CODE01", dd_desc:"Code 01 Desc"},
{dd_code:"CODE02", dd_desc:"Code 02 Desc"},
{dd_code:"CODE03", dd_desc:"Code 03 Desc"}
];
for(i = 0; i < lo_data.length; i++) {
console.log(" INS : " + i);
trans.executeSql (" insert into dummydata (dd_code, dd_desc) values (?, ?)", [lo_data[i].dd_code, lo_data[i].dd_desc], function(trans, results) {
la_promises.push(resolve(lo_result));
}, function(error) {
la_promises.push(reject(lo_result));
});
}
Promise.all(la_promises).then(function(results) {
console.log(" DEF DATA : DONE");
lo_result.db = lv_db;
resolve(lo_result);
}).catch(function() {
lo_result.db = null;
reject(lo_result);
});
});
});
}
根据所需的流程提供输出
BEGIN
INIT DB
INIT DB : DONE
DEF DATA
INS : 0
INS : 1
INS : 2
DEF DATA : DONE
END