编写承诺以使用传递两个参数的回调
Writing a promise to work with a callback that passes two arguments
在最近的一个 cordova 应用程序中,我们使用了 WebSQL api,因为它为我们提供了本地存储数据所需的设备支持和功能。我们将在即将进行的项目中再次使用它,因此我开始使用 implemented in core.js, using BabelJS 探索 promises。 编辑 添加了 link 承诺实施。
这是我目前的情况:
function getConnection () {
return window.openDatabase("cfa.db", "1.0", "CFA Database", 1000000);
}
function executeSql (transaction, query, args) {
return new Promise((resolve, reject) => {
console.log(query);
transaction.executeSql(query, args, resolve, reject);
});
}
function transaction (connection) {
return new Promise((resolve, reject) => {
connection.transaction(resolve, reject);
});
}
class DataSource {
executeSql (query, args) {
var connection = getConnection();
transaction(connection).then((tx) => {
return executeSql(tx, query, args);
}).then((tx, res) => {
console.log(tx, res.rows.length);
}, (tx, e) => {
console.log(e);
});
}
}
下面是使用 api 本身进行简单查询的准系统:
var connection = getConnection();
connection.transaction(function (tx, res) {
tx.executeSql("SELECT * FROM table", [], function (tx, res) {
console.log(res.rows.length);
}, function (tx, err) {
console.log(err);
});
}, function (err) {
console.log(err);
});
所以事务只是传递事务实例,我可以用它来执行 sql 语句。这很简单,可以包含一个承诺。比较棘手的部分是 executeSql
方法的回调。它传递事务,这很适合用于其他查询。然后它传递结果数据。我怎样才能把它包装在一个承诺中?
在我的 DataSource
class 中,那里的 executeSql 方法记录了一个事务对象,但没有记录 res 对象。然后交易正确触发,并且返回承诺应该有效。但我尊重它只有 returns 第一个参数。我该如何解决这个问题?
在您的 executeSql
方法中,您将 resolve
传递给 transaction.executeSQL
方法。
Promise 就像普通值一样 - 您不能 return 一个函数中的多个值 - 就像您无法解决具有多个值的 promise 一样。您的选择是要么用 [transaction, response]
数组解析它(并使用 babeljs 的 ES6 解构赋值),要么只用一个参数解析。在您的情况下,很明显您只对响应感兴趣。
function executeSQL(transaction, query, args){
return new Promise((resolve, reject) =>
transaction.executeSQL(query, args, (t,r) => resolve(r), reject);
);
}
请注意,您可以将 DataSource
class 重构为:
class DataSource{
async executeSQL(query, args){
let connection = getConnection();
let transaction = await transaction(connection);
let result = await executeSQL(transaction, query, args);
return result; // or console.log result.rows.length
}
}
你不需要在这里传递交易,因为你已经拥有它并且它为你解决的问题(上下文传递)不存在承诺。
由于您的意图是将这两个值作为承诺结果的一部分提供,我建议将它们包装在一个对象中,以便接收者可以提取它们:
function executeSql (transaction, query, args) {
return new Promise((resolve, reject) => {
console.log(query);
transaction.executeSql(query, args, (t, r) => resolve({
transaction: t,
result: r
}), reject);
});
}
用法:
transaction(connection)
.then(tx => executeSql(tx, query, args))
.then({result} => console.log(tx, result.rows.length),
e => console.log(e)
);
在最近的一个 cordova 应用程序中,我们使用了 WebSQL api,因为它为我们提供了本地存储数据所需的设备支持和功能。我们将在即将进行的项目中再次使用它,因此我开始使用 implemented in core.js, using BabelJS 探索 promises。 编辑 添加了 link 承诺实施。
这是我目前的情况:
function getConnection () {
return window.openDatabase("cfa.db", "1.0", "CFA Database", 1000000);
}
function executeSql (transaction, query, args) {
return new Promise((resolve, reject) => {
console.log(query);
transaction.executeSql(query, args, resolve, reject);
});
}
function transaction (connection) {
return new Promise((resolve, reject) => {
connection.transaction(resolve, reject);
});
}
class DataSource {
executeSql (query, args) {
var connection = getConnection();
transaction(connection).then((tx) => {
return executeSql(tx, query, args);
}).then((tx, res) => {
console.log(tx, res.rows.length);
}, (tx, e) => {
console.log(e);
});
}
}
下面是使用 api 本身进行简单查询的准系统:
var connection = getConnection();
connection.transaction(function (tx, res) {
tx.executeSql("SELECT * FROM table", [], function (tx, res) {
console.log(res.rows.length);
}, function (tx, err) {
console.log(err);
});
}, function (err) {
console.log(err);
});
所以事务只是传递事务实例,我可以用它来执行 sql 语句。这很简单,可以包含一个承诺。比较棘手的部分是 executeSql
方法的回调。它传递事务,这很适合用于其他查询。然后它传递结果数据。我怎样才能把它包装在一个承诺中?
在我的 DataSource
class 中,那里的 executeSql 方法记录了一个事务对象,但没有记录 res 对象。然后交易正确触发,并且返回承诺应该有效。但我尊重它只有 returns 第一个参数。我该如何解决这个问题?
在您的 executeSql
方法中,您将 resolve
传递给 transaction.executeSQL
方法。
Promise 就像普通值一样 - 您不能 return 一个函数中的多个值 - 就像您无法解决具有多个值的 promise 一样。您的选择是要么用 [transaction, response]
数组解析它(并使用 babeljs 的 ES6 解构赋值),要么只用一个参数解析。在您的情况下,很明显您只对响应感兴趣。
function executeSQL(transaction, query, args){
return new Promise((resolve, reject) =>
transaction.executeSQL(query, args, (t,r) => resolve(r), reject);
);
}
请注意,您可以将 DataSource
class 重构为:
class DataSource{
async executeSQL(query, args){
let connection = getConnection();
let transaction = await transaction(connection);
let result = await executeSQL(transaction, query, args);
return result; // or console.log result.rows.length
}
}
你不需要在这里传递交易,因为你已经拥有它并且它为你解决的问题(上下文传递)不存在承诺。
由于您的意图是将这两个值作为承诺结果的一部分提供,我建议将它们包装在一个对象中,以便接收者可以提取它们:
function executeSql (transaction, query, args) {
return new Promise((resolve, reject) => {
console.log(query);
transaction.executeSql(query, args, (t, r) => resolve({
transaction: t,
result: r
}), reject);
});
}
用法:
transaction(connection)
.then(tx => executeSql(tx, query, args))
.then({result} => console.log(tx, result.rows.length),
e => console.log(e)
);