Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/388.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 Firestore离线缓存&;承诺_Javascript_Google Cloud Firestore_Offline - Fatal编程技术网

Javascript Firestore离线缓存&;承诺

Javascript Firestore离线缓存&;承诺,javascript,google-cloud-firestore,offline,Javascript,Google Cloud Firestore,Offline,这是一个后续问题。我已经读过离线缓存,但有一点我很困惑 一位评论者在上一个问题中(大约一年前)回答: 与数据库交互的Android代码将是相同的 无论您是否连接,因为SDK的工作原理都是一样的。” 在这封信里,我注意到上面写着: 返回 包含无效的非无效承诺一种一次性解决的承诺 数据已成功写入后端。(请注意 脱机时将无法解决) 重点是我的。文档中的这一点是否表明代码的行为不一样,或者我是否遗漏了什么?如果我在允许某些用户交互之前等待.set()的解析,从这一点听起来,我需要为脱机情况调整代码,与正

这是一个后续问题。我已经读过离线缓存,但有一点我很困惑

一位评论者在上一个问题中(大约一年前)回答:

与数据库交互的Android代码将是相同的 无论您是否连接,因为SDK的工作原理都是一样的。”

在这封信里,我注意到上面写着:

返回
包含无效的非无效承诺
一种一次性解决的承诺 数据已成功写入后端。(请注意 脱机时将无法解决)

重点是我的。文档中的这一点是否表明代码的行为不一样,或者我是否遗漏了什么?如果我在允许某些用户交互之前等待.set()的解析,从这一点听起来,我需要为脱机情况调整代码,与正常情况不同

这让我更担心。它没有完全相同的音符,但上面写着(我的):

在将新创建的文档写入后端后,使用指向该文档的DocumentReference进行解析的承诺

这有点模糊,因为不确定本例中的“backend”是“cache”和“server”的超集,还是仅表示服务器。如果这一个不解析,则表示以下操作不起作用,对吗

return new Promise((resolve, reject) => {
  let ref = firestore.collection(path)
  ref.add(data)
  .then(doc => {
    resolve({ id: doc.id, data: data })
  })
  ...
})

也就是说,.add()无法解析,.then()不会运行,我也无法访问刚刚添加的文档的
id
。我希望我只是误解了一些东西,我的代码可以继续在线和离线运行。

这里有两个问题,它们并不真正相关。我将分别解释这两个问题

在大多数情况下,开发人员通常不关心文档更新的承诺是否真的得到了解决,这几乎总是“一劳永逸”“。如果应用程序的行为方式与服务器相同,那么应用程序知道更新击中服务器会有什么好处?本地缓存已经更新,将来的所有查询都将显示文档已经更新,即使更新尚未与服务器同步

这方面的主要例外是事务。要求服务器联机,因为需要在客户端和服务器之间进行往返,以确保更新是原子的。事务不能脱机工作。如果你需要知道交易是否有效,你需要在线。与正常的文档写入不同,事务不会持久存在于本地缓存中。如果在服务器上完成事务之前终止应用程序,则事务将丢失


第二个问题是新添加的文档,在更新时没有定义文档的id。确实,
add()
返回的承诺只有在服务器上存在新文档时才能解析。在承诺向您提供新文档的
DocumentReference
之前,您无法知道文档的id


如果此行为不适用于您,您可以通过不带参数的调用而不是
add()
为文档生成新id
doc()
立即返回尚未写入的新(未来)文档的DocumentReference(直到您选择写入)。无论是
doc()
还是
add()
,这些DocumentReference对象都包含在客户端上生成的唯一ID。不同之处在于,使用
doc()
,您可以立即使用id,因为您可以立即获得DocumentReference。使用
add()
,您不能这样做,因为在承诺解决之前不会提供DocumentReference。如果您现在需要新的文档id,即使在脱机状态下,也可以使用
doc()
而不是
add()
。然后,您可以使用返回的DocumentReference离线创建文档,存储在本地缓存中,并在以后进行同步。然后,更新将返回一个承诺,该承诺将在文档实际编写时得到解决。

您将这个问题标记为“android”,但由于本机android开发不涉及承诺,我将其更改为“javascript”。本机android包含任务对象,它们相似,但不相同。@DougStevenson-很好。谢谢你修好了。非常有帮助,谢谢!1) 听起来我需要重新安排我的离线模式,这与过去的经验不同。在我的UI中,添加文档后(在“添加模式”屏幕中),它会切换到同一文档的“查看模式”。在我目前的想法中,它不会切换到新的模式,直到它获得成功的确认。我会努力改用火,忘记思考。问:如果写入缓存时出现问题,那么.是否仍会着火?2) 我错过了doc()和add()的区别。这绝对解决了我的问题,并为我提供了一个能够脱机的路径转发。我不知道如果缓存写入失败,错误处理会是什么样子。这将是非常罕见的(可能磁盘空间不足?)。但我希望这个承诺会被拒绝。顺便说一句,有时给用户一个指示器,表明他们的更新与服务器完全同步是很有用的。例如,在聊天室中,用户可能想知道其他人是否能看到他们的消息。您可以触发并忘记该消息,但这是对用户的一种礼貌,让他们知道该消息发生了什么。不管怎样,你都不想阻止他们发送更多的消息。