Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 编写使用传递两个参数的回调的承诺_Javascript_Promise_Web Sql_Babeljs - Fatal编程技术网

Javascript 编写使用传递两个参数的回调的承诺

Javascript 编写使用传递两个参数的回调的承诺,javascript,promise,web-sql,babeljs,Javascript,Promise,Web Sql,Babeljs,在最近的cordova应用程序中,我们使用了WebSQL api,因为它为我们提供了本地存储数据所需的设备支持和功能。我们将在一个即将到来的项目中再次使用它,所以我开始用它来探索承诺编辑添加了承诺实施的链接 以下是我目前掌握的情况: function getConnection () { return window.openDatabase("cfa.db", "1.0", "CFA Database", 1000000); } function executeSql (transacti

在最近的cordova应用程序中,我们使用了WebSQL api,因为它为我们提供了本地存储数据所需的设备支持和功能。我们将在一个即将到来的项目中再次使用它,所以我开始用它来探索承诺编辑添加了承诺实施的链接

以下是我目前掌握的情况:

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
类中,那里的executeSql方法记录一个事务对象,但不记录res对象。然后,事务将正确启动,并返回承诺。但我尊重它只返回第一个参数。我该如何解决这个问题?

executeSql
方法中,您将
resolve
传递给
事务.executeSql
方法

承诺与普通值类似—您不能从函数返回多个值—就像您不能用多个值解析承诺一样。您可以选择使用
[transaction,response]
数组(并使用babeljs的ES6解构赋值)或只使用一个参数进行解析。就你而言,很明显你只对回应感兴趣

function executeSQL(transaction, query, args){
    return new Promise((resolve, reject) =>
        transaction.executeSQL(query, args, (t,r) => resolve(r), reject);
    );
}
请注意,您可以将
数据源
类重构为:

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)
);

您能将该回调包装成一个返回一个合并结果的函数吗?您的意思是让事务和执行sql在一个承诺中完成吗?@agmcleod请确保使用最新版本和更新的core js,22小时前才有更多可调试的承诺:)无论哪种情况,如果你的应用程序在手机上运行,我强烈推荐bluebird支持core js。享受您没有内存限制的事实,选择更强大、更快、更可调试的实现。您可以告诉babel使用bluebird协程标志编译异步函数。实际上,我对这两个都感兴趣,因为如果需要的话,返回事务将使链接查询变得更容易。使用数组编辑示例非常简单。@agmcleod请确保使用数组解构语法-如果您愿意,我可以在答案中添加一个这样做的示例。再次感谢。鉴于ES7在编译器中是实验性的,它是否值得用于将交付给客户机的东西?尽管如此,我还是很喜欢它的简洁:)是的-你无论如何都在使用构建步骤,最好是充分利用itES6箭头函数,允许省略
{}
s和
return
,如果它是一行,那么
(tx)=>{return executeSQL(tx,query,args);}
实际上可以是
tx=>executeSQL(tx,query,args)
。此外,您还可以在第二种情况下使用对象分解。@BenjaminGruenbaum,谢谢。我的解构正确吗?事实上,我从未接触过ES6。是的,在我看来不错,你可以分解更多级别,但公平地说,我不确定ES6是否允许这样做,或者只是巴贝尔。