【问题标题】:How to deal with async function results in JavaScriptJavaScript中如何处理异步函数结果
【发布时间】:2012-03-14 21:23:38
【问题描述】:

来自 c# 背景,我可能从一个完全错误的角度看待 JavaScript,所以请多多包涵。

暂时搁置异步的优势, 假设我只是想从 HTML5 页面中的 SQLite 数据库中检索一个值。 我想看到的是这样的

var something = db.getPicture(1);

现在考虑一个(可能非常幼稚的)实现:

this.getPicture(id)
{
    this.database.transaction(function(tx)
    {
        tx.executeSql('SELECT ......', null, function(tx, results)
        {
            if (results.rows.length == 1)
                return results.rows.items(0).Url; //This of course does not resturn
                                                    //anything to the caller of .getPicture(id)
        }
    },
    function(error)
    {
        //do some error handling
    },
    function(tx)
    {
        //no error
    });                     
}

首先,这是一大堆嵌套函数,其次……我无法将从数据库中得到的结果作为 .getPicture() 函数的值返回。

这是简单的版本,如果我想先从表中检索索引怎么办? 然后在下一个查询中使用该索引,依此类推......

这对于 JavaScript 开发人员来说是否正常,我是否完全错误,是否有解决方案等...

【问题讨论】:

  • 是的,你完全错了 :-) 为了处理事物的异步性质,你传递 callback 函数。这些是由运行时系统在需要时调用的,因此从回调中返回值没有任何意义。
  • 要让 getPicture 返回某些内容,您需要阻止 getPicture 的执行,直到异步内容完成,并使用异步回调填充返回变量。
  • @Pointy:考虑将您的评论升级为答案
  • @KeesdeKooter 确实这是一个非常常见的问题;我一直在寻找一个好的副本。

标签: javascript html sqlite


【解决方案1】:

JavaScript 中遵循的基本模式(在 Web 浏览器或 Node.js 等异步环境中)是,您需要在操作完成时执行的工作应该发生在 API 提供的“成功”回调中。在您的情况下,这就是传递给您的“executeSql()”方法的函数。

this.getPicture = function(id, whenFinished)
{
    this.database.transaction(function(tx)
    {
        tx.executeSql('SELECT ......', null, function(tx, results)
        {
            if (results.rows.length == 1)
                whenFinished(results.rows.items(0).Url);
        }
    },

在该设置中,数据库操作的结果作为参数传递给调用“getPicture()”时提供的函数。

因为 JavaScript 函数形成 闭包,它们可以访问调用上下文中的局部变量。也就是说,作为“whenFinished”参数传递给“getPicture()”的函数将可以访问在调用“getPicture()”时存在的局部变量。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-05-29
    • 1970-01-01
    • 1970-01-01
    • 2021-08-01
    • 1970-01-01
    • 2023-01-16
    • 2011-08-14
    相关资源
    最近更新 更多