尝试与 JS API 交互,但在由 Grunt 任务运行时失败;我觉得我的逻辑很困惑。我的步骤:
check_tokens)refresh_tokens)authorize_with_api) <->->authorize_with_api 错误拒绝或使用 token 解决目前 Grunt 任务报告一个 UnhandledPromiseRejectionWarning 并且永远不会完成。如果我注释掉对 authorize_with_api 的调用,它会正确退出并出现错误,并且我会打印最上面的 caught error! 消息。
为什么我不能从执行函数中返回一个 promise ?我的逻辑有什么问题?
/* global sdk, config, tokens */
return getTokens().then((p_tokens) => {
tokens = p_tokens;
return check_tokens(tokens);
}).then((tokens) => {
console.log('then() is called!');
}).catch((err) => {
console.error('caught error!', err);
});
function check_tokens(tokens) {
if(are_old(tokens)) { // returns true
return refresh_tokens(tokens);
}
return Promise.resolve(tokens);
}
function refresh_tokens(tokens) {
return new Promise(function(resolve, reject) {
sdk.refreshTokens(tokens.refresh_token, function(err, new_tokens) {
if(err) {
if(error.code === 'invalid_grant') {
return authorize_with_api();
}
reject('refreshTokens failed');
} else if(newTokens) {
resolve(new_tokens);
}
});
});
}
function authorize_with_api() {
return new Promise(function(resolve, reject) {
sdk.getTokens(config.auth_code, function(err, tokens) {
if(err) {
reject('getTokens failed');
} else if(tokens) {
resolve(tokens);
}
});
});
}
最佳答案
从 Promise 构造函数(或其中的任何函数)返回并不会解析 promise:
return new Promise(function(resolve, reject) {
sdk.refreshTokens(..., function(err, new_tokens) {
if(error.code === 'invalid_grant') {
return authorize_with_api();
} // ^--- this will not chain to the promise being created.
即使您没有从 sdk.refreshTokens 回调中返回,而是直接使用没有回调的 return authorize_with_api(),结果仍然不会被束缚。
要解决 promise ,您不能从其构造函数返回,而必须显式调用给定回调之一(解决/拒绝):
return new Promise(function(resolve, reject) {
sdk.refreshTokens(..., function(err, new_tokens) {
if(error.code === 'invalid_grant') {
resolve(authorize_with_api());
} // ^--- must call resolve here
解决 promise 实际上也会处理拒绝,因此无论 authorize_with_api 是解决还是拒绝,状态都会相应地向上传播。
我的建议是仍然保留 return 语句,以维持 if 分支的预期视觉语义,条件是提前返回,但代码在没有它的情况下也能工作,因为 Promises can only be resolved once 和所有对 reject/resolve 的进一步调用都将被忽略。
return new Promise(function(resolve, reject) {
sdk.refreshTokens(..., function(err, new_tokens) {
if(error.code === 'invalid_grant') {
return resolve(authorize_with_api());
} // ^--- should still return here for readability - clean logic purposes
reject('refreshTokens failed'); // this will be ignored if the above `resolve` gets called first, no matter if you have the `return` statement
例子:
function success() {
return Promise.resolve('success');
}
function error() {
return Promise.reject('error');
}
function alwaysPending() {
return new Promise(() => {
return success();
});
}
function resolves() {
return new Promise((resolve) => {
resolve(success());
});
}
function rejects() {
return new Promise((resolve) => {
resolve(error());
});
}
alwaysPending().then(console.log); // doesn't log anything
resolves().then(console.log);
rejects().catch(console.log);
关于javascript - 从执行函数返回 promise ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41488363/
我在使用omniauth/openid时遇到了一些麻烦。在尝试进行身份验证时,我在日志中发现了这一点:OpenID::FetchingError:Errorfetchinghttps://www.google.com/accounts/o8/.well-known/host-meta?hd=profiles.google.com%2Fmy_username:undefinedmethod`io'fornil:NilClass重要的是undefinedmethodio'fornil:NilClass来自openid/fetchers.rb,在下面的代码片段中:moduleNetclass
为什么4.1%2返回0.0999999999999996?但是4.2%2==0.2。 最佳答案 参见此处:WhatEveryProgrammerShouldKnowAboutFloating-PointArithmetic实数是无限的。计算机使用的位数有限(今天是32位、64位)。因此计算机进行的浮点运算不能代表所有的实数。0.1是这些数字之一。请注意,这不是与Ruby相关的问题,而是与所有编程语言相关的问题,因为它来自计算机表示实数的方式。 关于ruby-为什么4.1%2使用Ruby返
我想在一个没有Sass引擎的类中使用Sass颜色函数。我已经在项目中使用了sassgem,所以我认为搭载会像以下一样简单:classRectangleincludeSass::Script::FunctionsdefcolorSass::Script::Color.new([0x82,0x39,0x06])enddefrender#hamlengineexecutedwithcontextofself#sothatwithintemlateicouldcall#%stop{offset:'0%',stop:{color:lighten(color)}}endend更新:参见上面的#re
我遵循了教程http://gettingstartedwithchef.com/,第1章。我的运行list是"run_list":["recipe[apt]","recipe[phpap]"]我的phpapRecipe默认Recipeinclude_recipe"apache2"include_recipe"build-essential"include_recipe"openssl"include_recipe"mysql::client"include_recipe"mysql::server"include_recipe"php"include_recipe"php::modul
我正在尝试用ruby中的gsub函数替换字符串中的某些单词,但有时效果很好,在某些情况下会出现此错误?这种格式有什么问题吗NoMethodError(undefinedmethod`gsub!'fornil:NilClass):模型.rbclassTest"replacethisID1",WAY=>"replacethisID2andID3",DELTA=>"replacethisID4"}end另一个模型.rbclassCheck 最佳答案 啊,我找到了!gsub!是一个非常奇怪的方法。首先,它替换了字符串,所以它实际上修改了
我有一个包含多个键的散列和一个字符串,该字符串不包含散列中的任何键或包含一个键。h={"k1"=>"v1","k2"=>"v2","k3"=>"v3"}s="thisisanexamplestringthatmightoccurwithakeysomewhereinthestringk1(withspecialcharacterslike(^&*$#@!^&&*))"检查s是否包含h中的任何键的最佳方法是什么,如果包含,则返回它包含的键的值?例如,对于上面的h和s的例子,输出应该是v1。编辑:只有字符串是用户定义的。哈希将始终相同。 最佳答案
我有一些代码在几个不同的位置之一运行:作为具有调试输出的命令行工具,作为不接受任何输出的更大程序的一部分,以及在Rails环境中。有时我需要根据代码的位置对代码进行细微的更改,我意识到以下样式似乎可行:print"Testingnestedfunctionsdefined\n"CLI=trueifCLIdeftest_printprint"CommandLineVersion\n"endelsedeftest_printprint"ReleaseVersion\n"endendtest_print()这导致:TestingnestedfunctionsdefinedCommandLin
我在用Ruby执行简单任务时遇到了一件奇怪的事情。我只想用每个方法迭代字母表,但迭代在执行中先进行:alfawit=("a".."z")puts"That'sanalphabet:\n\n#{alfawit.each{|litera|putslitera}}"这段代码的结果是:(缩写)abc⋮xyzThat'sanalphabet:a..z知道为什么它会这样工作或者我做错了什么吗?提前致谢。 最佳答案 因为您的each调用被插入到在固定字符串之前执行的字符串文字中。此外,each返回一个Enumerable,实际上您甚至打印它。试试
所以我开始关注ruby,很多东西看起来不错,但我对隐式return语句很反感。我理解默认情况下让所有内容返回self或nil但不是语句的最后一个值。对我来说,它看起来非常脆弱(尤其是)如果你正在使用一个不打算返回某些东西的方法(尤其是一个改变状态/破坏性方法的函数!),其他人可能最终依赖于一个返回对方法的目的并不重要,并且有很大的改变机会。隐式返回有什么意义?有没有办法让事情变得更简单?总是有返回以防止隐含返回被认为是好的做法吗?我是不是太担心这个了?附言当人们想要从方法中返回特定的东西时,他们是否经常使用隐式返回,这不是让你组中的其他人更容易破坏彼此的代码吗?当然,记录一切并给出
如何检查Ruby文件是否是通过“require”或“load”导入的,而不是简单地从命令行执行的?例如:foo.rb的内容:puts"Hello"bar.rb的内容require'foo'输出:$./foo.rbHello$./bar.rbHello基本上,我想调用bar.rb以不执行puts调用。 最佳答案 将foo.rb改为:if__FILE__==$0puts"Hello"end检查__FILE__-当前ruby文件的名称-与$0-正在运行的脚本的名称。 关于ruby-检查是否