【发布时间】:2011-12-09 16:03:31
【问题描述】:
我遇到了一个有趣的情况,我通常聪明的头脑无法想出解决方案:) 这是情况......
我有一个具有 get() 方法的类...调用此方法以获取存储的用户首选项...它所做的是调用一些底层提供程序以实际获取数据...如现在所写,它正在调用一个与 cookie 对话的提供者……所以, get() 调用 providerGet() 假设,providerGet() 返回一个值,而 get() 将其传递给调用者。调用者在明显继续其工作之前期望得到响应。
这是棘手的部分......我现在正在尝试实现一个本质上是异步的提供程序(在这种情况下使用本地存储)......所以,providerGet() 将立即返回,已调度调用本地存储将在一段时间后调用传递给它的回调函数......但是,由于 providerGet() 已经返回,get() 现在通过对原始调用的扩展也返回了,它显然没有返回实际检索到的数据。
所以,问题只是有没有办法从本质上“阻止” providerGet() 的返回,直到异步调用返回?请注意,出于我的目的,我并不关心这可能对性能产生的影响,我只是想弄清楚如何让它发挥作用。
我不认为有办法,当然我知道我无法想出它......所以我想把它扔掉,看看其他人能想出什么:)
编辑:我现在才知道问题的核心,即 web sql API 是异步的,可能有一个解决方案......原来也有一个同步版本的 API,我没有'没有意识到......我现在正在阅读文档以了解如何使用它,但这会很好地解决问题,因为providerGet()被异步编写的唯一原因是允许该提供者......代码get() 是我自己在各种存储提供程序(cookies、web sql、localStorage 等)之上的抽象层的一部分,因此必须以最低的公分母获胜,这意味着如果一个是异步的,它们都必须是异步的。 . 唯一的一个是 web sql ......所以如果有办法同步地做到这一点,我的观点就变得毫无意义(但我认为这仍然是一个有趣的问题)
edit2:啊,好吧,似乎没有帮助......似乎API的同步版本没有在任何浏览器中实现,即使它指定它只能从工作线程中使用,所以这个无论如何,它似乎没有帮助。虽然,读一些其他的东西,听起来好像有一种方法可以使用递归来解决这个问题......我现在正在整理一些测试代码,如果/当我让它工作时,我会发布它,看起来很有趣一般地解决任何此类情况的方法。
edit3:根据我下面的 cmets,真的没有办法完全按照我的意愿去做。我要解决我的直接问题的解决方案是根本不允许使用 Web SQL 进行数据存储。这不是理想的解决方案,但由于该规范在不断变化并且没有被广泛实施,所以它不是世界末日......希望当它得到适当支持时,同步版本将可用,我可以为它插入一个新的提供程序并且走吧。不过一般来说,似乎没有任何方法可以解决这个奇迹......证实了我的预期,但希望我这次错了:)
【问题讨论】:
-
不,真的没有办法做到这一点。真正的解决方案是反转您的 API,以便将您自己的“get()”传递给回调。
-
如果您无法更改 API,另一种可能性是在加载时(或其他)以某种方式将本地存储中存储的任何内容直接迁移到页面中。如果没有太多存储,那么这将允许您在需要时从“providerGet()”实现直接访问它。
-
看看这个项目。它可能就在你的小巷里......github.com/JeffreyZhao/jscex
-
使用外部状态和进度检查,你有时可以抛出 setTimeout(arguments.callee.bind(this,arguments,100); 稍后再接,但你的老板不会喜欢那种代码。 ..
标签: javascript blocking