- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我为 Dynamics CRM REST/ODATA webservice 开发了一个小库(CrmRestKit)。该库依赖于 jQuery 并使用 promise-pattern,分别是 jQuery 的 promise-like-pattern。
现在我想将这个库移植到 bluebird并删除 jQuery 依赖项。但是我遇到了一个问题,因为bluebird不支持promise-objects的同步解析。
一些上下文信息:
CrmRestKit 的 API 除了一个可选参数外,该参数定义了网络服务调用应该以同步还是异步模式执行:
CrmRestKit.Create( 'Account', { Name: "foobar" }, false ).then( function ( data ) {
....
} );
当您传递“true”或省略最后一个参数时,该方法将同步创建记录。模式。
有时需要在同步模式下执行操作,例如您可以为 Dynamics CRM 编写 JavaScript 代码,该代码涉及表单的保存事件,并且在此事件处理程序中您需要执行同步操作用于验证(例如,验证是否存在一定数量的子记录,如果存在正确数量的记录,则取消保存操作并显示错误消息)。
我现在的问题是:bluebird 不支持同步模式下的分辨率。例如,当我执行以下操作时,将以异步方式调用“then”处理程序:
function print( text ){
console.log( 'print -> %s', text );
return text;
}
///
/// 'Promise.cast' cast the given value to a trusted promise.
///
function getSomeTextSimpleCast( opt_text ){
var text = opt_text || 'Some fancy text-value';
return Promise.cast( text );
}
getSomeTextSimpleCast('first').then(print);
print('second');
输出如下:
print -> second
print -> first
我希望“第二个”出现在“第一个”之后,因为 promise 已经用一个值解决了。因此,我假设当应用于已解析的 promise 对象时 立即调用 then-event-handler。
当我用 jQuery 做同样的事情(在已经解决的 promise 上使用 then)时,我将得到预期的结果:
function jQueryResolved( opt_text ){
var text = opt_text || 'jQuery-Test Value',
dfd = new $.Deferred();
dfd.resolve(text);
// return an already resolved promise
return dfd.promise();
}
jQueryResolved('third').then(print);
print('fourth');
这将生成以下输出:
print -> third
print -> fourth
有没有办法让 Bluebird 以同样的方式工作?
更新:提供的代码只是为了说明问题。 lib 的想法是:无论执行模式如何(同步、异步),调用者将始终处理 promise 对象。
关于“...询问用户...似乎没有任何意义”:当您提供“CreateAsync”和“CreateSync”两种方法时,也由用户决定如何执行操作.
无论如何,当前实现的默认行为(最后一个参数是可选的)是异步执行。所以 99% 的代码需要一个 promise-object,可选参数只用于 1% 的情况,你只需要一个同步执行。此外,我为自己开发了 lib,并且在 99,9999% 的情况下我使用异步模式,但我认为可以选择随心所欲地走同步之路是件好事。
但我认为我理解了同步方法应该简单地返回值的要点。对于下一个版本 (3.0),我将实现“CreateSync”和“CreateAsync”。
感谢您的输入。
更新 2我对可选参数的意图是确保一致的行为并防止逻辑错误。假设您是我使用 lib 的方法“GetCurrentUserRoles”的消费者。所以该方法将始终返回一个 promise ,这意味着您必须使用“then”方法来执行依赖于结果的代码。所以当有人写这样的代码时,我同意这是完全错误的:
var currentUserRoels = null;
GetCurrentUserRoles().then(function(roles){
currentUserRoels = roles;
});
if( currentUserRoels.indexOf('foobar') === -1 ){
// ...
}
我同意,当“GetCurrentUserRoles”方法从同步更改为异步时,此代码将中断。
但我知道这不是一个好的设计,因为消费者现在应该处理异步方法。
最佳答案
简短版本:我明白你为什么要这样做,但答案是否定的。
我认为被问到的根本问题是,如果 promise 已经完成,完成的 promise 是否应该立即运行回调。我可以想到很多可能发生这种情况的原因——例如,一个异步保存过程只在发生更改时才保存数据。它可能能够以同步方式从客户端检测更改,而无需通过外部资源,但如果检测到更改,那么并且只有在那时才需要异步操作。
在具有异步调用的其他环境中,模式似乎是开发人员负责了解他们的工作可能会立即完成(例如,.NET Framework 的异步模式实现适应了这一点)。这不是框架的设计问题,而是它的实现方式。
JavaScript 的开发人员(以及上面的许多评论者)对此似乎有不同的观点,坚持认为如果某些东西可能是异步的,那么它必须始终是异步的。这是否“正确”并不重要——根据我在 https://promisesaplus.com/ 找到的规范, item 2.2.4 声明基本上没有回调可以被调用,直到你离开我将称之为“脚本代码”或“用户代码”的地方;也就是说,规范明确指出,即使 promise 已完成,您也不能立即调用回调。我检查了其他几个地方,他们要么对这个话题什么也没说,要么同意原始来源。我不知道https://promisesaplus.com/可以被认为是这方面的权威信息来源,但我看到没有其他来源不同意它,而且它似乎是最完整的。
这个限制有点武断,坦率地说,我更喜欢 .NET 的观点。我会留给其他人来决定他们是否认为以看起来异步的方式执行可能同步或不同步的事情是“糟糕的代码”。
您的实际问题是 Bluebird 是否可以配置为执行非 JavaScript 行为。在性能方面,这样做可能会有一点好处,如果你足够努力,在 JavaScript 中一切皆有可能,但随着 Promise 对象在平台上变得越来越普遍,你会看到将其用作 native 组件而不是自定义编写的转变polyfill 或库。因此,无论今天的答案是什么,在 Bluebird 中修改 promise 很可能会在未来给您带来问题,并且您的代码可能不应该被编写为依赖于 promise 或提供 promise 的立即解决方案。
关于javascript - 同步 promise 解析(bluebird vs. jQuery),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21136283/
我一直在使用 AJAX 从我正在创建的网络服务中解析 JSON 数组时遇到问题。我的前端是一个简单的 ajax 和 jquery 组合,用于显示从我正在创建的网络服务返回的结果。 尽管知道我的数据库查
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
我在尝试运行 Android 应用程序时遇到问题并收到以下错误 java.lang.NoClassDefFoundError: com.parse.Parse 当我尝试运行该应用时。 最佳答案 在这
有什么办法可以防止etree在解析HTML内容时解析HTML实体吗? html = etree.HTML('&') html.find('.//body').text 这给了我 '&' 但我想
我有一个有点疯狂的例子,但对于那些 JavaScript 函数作用域专家来说,它看起来是一个很好的练习: (function (global) { // our module number one
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 8 年前。 Improve th
我需要编写一个脚本来获取链接并解析链接页面的 HTML 以提取标题和其他一些数据,例如可能是简短的描述,就像您链接到 Facebook 上的内容一样。 当用户向站点添加链接时将调用它,因此在客户端启动
在 VS Code 中本地开发时,包解析为 C:/Users//AppData/Local/Microsoft/TypeScript/3.5/node_modules/@types//index而不是
我在将 json 从 php 解析为 javascript 时遇到问题 这是我的示例代码: //function MethodAjax = function (wsFile, param) {
我在将 json 从 php 解析为 javascript 时遇到问题 这是我的示例代码: //function MethodAjax = function (wsFile, param) {
我被赋予了将一种语言“翻译”成另一种语言的工作。对于使用正则表达式的简单逐行方法来说,源代码过于灵活(复杂)。我在哪里可以了解更多关于词法分析和解析器的信息? 最佳答案 如果你想对这个主题产生“情绪化
您好,我在解析此文本时遇到问题 { { { {[system1];1;1;0.612509325}; {[system2];1;
我正在为 adobe after effects 在 extendscript 中编写一些代码,最终变成了 javascript。 我有一个数组,我想只搜索单词“assemble”并返回整个 jc3_
我有这段代码: $(document).ready(function() { // }); 问题:FB_RequireFeatures block 外部的代码先于其内部的代码执行。因此 who
背景: netcore项目中有些服务是在通过中间件来通信的,比如orleans组件。它里面服务和客户端会指定网关和端口,我们只需要开放客户端给外界,服务端关闭端口。相当于去掉host,这样省掉了些
1.首先贴上我试验成功的代码 复制代码 代码如下: protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
什么是 XML? XML 指可扩展标记语言(eXtensible Markup Language),标准通用标记语言的子集,是一种用于标记电子文件使其具有结构性的标记语言。 你可以通过本站学习 X
【PHP代码】 复制代码 代码如下: $stmt = mssql_init('P__Global_Test', $conn) or die("initialize sto
在SQL查询分析器执行以下代码就可以了。 复制代码代码如下: declare @t varchar(255),@c varchar(255) declare table_cursor curs
前言 最近练习了一些前端算法题,现在做个总结,以下题目都是个人写法,并不是标准答案,如有错误欢迎指出,有对某道题有新的想法的友友也可以在评论区发表想法,互相学习🤭 题目 题目一: 二维数组中的
我是一名优秀的程序员,十分优秀!