关于创建相互依赖的异步调用的建议
Posted
技术标签:
【中文标题】关于创建相互依赖的异步调用的建议【英文标题】:Advice on creating asynchronous calls that depend on each other 【发布时间】:2016-05-12 23:11:08 【问题描述】:我正在尝试创建一个库来对 Web 应用程序进行 API 调用(jira,如果你想知道的话)我的 api 调用工作没有问题,但我希望使代码更具可读性和使用-有能力的。我已经尝试搜索我的需求,但结果我不确定我需要搜索什么。
我遇到了相互依赖的异步调用的问题,我知道我必须等到运行回调才能运行我的下一个项目,但我不确定设计它的最佳方法。
我真的很想将链接作为我的 api 的一个功能,我希望它看起来像这样:
createProject(jsonProjectStuff)
.setLeadUser("myusername")
.createBoard("boardName")
.setBoardPermissions(boardPermissionJSONvar)
.addRole(personRoleJSONvar);
在这个例子中,一切都必须等待createProject
,因为它将返回项目。 createBoard
通常不依赖于项目,但在这种情况下使用它应该“分配”给所做的项目,设置董事会权限仅依赖于 createBoard
工作。 addRole
再次特定于项目。
我的问题是:
-
是否可以像这样切换上下文并在它们之间保留数据,而无需从硬编码的响应中运行函数?
如果这是可能的,这是个好主意吗?如果不是,我愿意接受其他计划。
我可以想出几种让它工作的方法,包括使用依赖树注册函数调用,然后在我们进行时履行承诺,尽管此时这对我来说主要是概念性的,因为我正在努力决定最好的.
2016 年 2 月 19 日编辑
因此,我对此进行了更多研究,并决定仅在创建新项目与父项不直接相关时才使用选择性“then”。
//Numbers are ID, string is Name
copyProject(IDorName)
.setRoles(JSONItem)
.setOwner("Project.Owner")
.setDefaultEmail("noreply@fake.com")
.then(
copyBoard(IDorName)
.setName("Blah blah Name project.key"),
saveFilterAs(IDorName, "Board project.key",
"project = project.key ORDER BY Rank ASC")
.setFilterPermissions(shareValuesJSON)
)
我非常喜欢这个解决方案,我唯一不知道该怎么做的是字符串“变量”,我想它可能是"Blah blah Name " + this.project.key
无论哪种方式,我都不确定如何通过“then”函数让copyBoard
或saveFilterAs
访问它。
有什么想法吗?
【问题讨论】:
这似乎是个好主意...您可以存储最后一个promise,并且对于每个调用的函数,您可以链接到最后一个promise,并更新最后一个promise变量。 @JoaozitoPolo 在调用需要第一次调用中的变量的深度 4 函数的上下文中,这将如何工作,您介意展示一个简单的示例,以便我可以修改并将其用于我的需要吗? 相关:Combining promises and chaining。从本质上讲,javascript 足够灵活,可以支持您想象的任何异步流畅模式,但它们不一定具有高性能或易于实现。 我们仍在使用事件系统,但我期待反应式编程检查 github.com/ReactiveX/rxandroid/wiki 在那里您可以观察和订阅 @Krum110487:给定箭头函数,上下文并不是什么问题。一般来说,我认为让实例的状态与承诺相关联是一个坏主意,而不是为具有明确定义的状态的实例做出承诺(另见here)。当然,这对实例上的方法链接是有害的;尽管如此,如果你坚持使用流畅的接口,你不应该放弃这个原则——而是围绕实例的 Promise 构建第二个类,并为其提供可链接的方法。 【参考方案1】:我最近一直在使用 Nightmare(无头浏览器)。
它有一个流畅的 API,使用了很好的设计模式。
调用 API 不会直接执行操作,它只会将它们排队,当您准备好执行时,您必须调用返回承诺的 end
函数。当队列完成异步执行时,promise 就被解决了。
比如你的情况
createProject(jsonProjectStuff)
.setLeadUser("myusername")
.createBoard("boardName")
.setBoardPermissions(boardPermissionJSONvar)
.addRole(personRoleJSONvar)
.end() // Execute the queue of operations.
.then() =>
// All operations completed.
))
.catch(err =>
// An error occurred.
);
我觉得这种模式很优雅。它允许您拥有一个流畅的 API 来构建一系列操作。然后,当您准备好执行上述操作时,您调用end
(或其他)。然后异步完成操作序列,并使用 Promise 处理完成和错误。
【讨论】:
以上是关于关于创建相互依赖的异步调用的建议的主要内容,如果未能解决你的问题,请参考以下文章