Javascript 在if/else中处理承诺
我有一个条件语句,其中我需要执行两个操作中的一个,然后在哪个操作解决后继续。因此,我的代码目前如下所示:Javascript 在if/else中处理承诺,javascript,promise,Javascript,Promise,我有一个条件语句,其中我需要执行两个操作中的一个,然后在哪个操作解决后继续。因此,我的代码目前如下所示: if (shoud_do_thing_a) { //should_do_thing_a is just a variable that determines which function to call. it is not a promise do_thing_a() } else { do_thing_b() } // more code 问题是do\u thing\u a和
if (shoud_do_thing_a) { //should_do_thing_a is just a variable that determines which function to call. it is not a promise
do_thing_a()
} else {
do_thing_b()
}
// more code
问题是do\u thing\u a
和do\u thing\u b
都是返回承诺,我不能继续,直到执行的任何一个都解决了。我想出的解决这个问题的最好办法是:
var more_code = function () {
// more code
}
if (shoud_do_thing_a) {
do_thing_a().then(more_code)
} else {
do_thing_b().then(more_code)
}
我不喜欢这种结构。这很难理解,因为您需要跳转以找到定义了更多\u code
的位置(假设我在多个位置有这种类型的控制流),而不是简单地继续阅读
在javascript中有没有更好的方法来处理这类问题?如果可以使用async/await
async function someFunc() {
var more_code = function () {
// more code
}
if (shoud_do_thing_a) {
await do_thing_a()
} else {
await do_thing_b()
}
more_code()
}
如果不能,请使用then()
:
您可以使用
async/await
async function fn() {
let p, result;
if (shoud_do_thing_a) {
p = await do_thing_a()
} else {
p = await do_thing_b()
}
if (p) {
result = more_code();
}
return result
}
保存承诺并在if语句后添加then:
var promise;
if (shoud_do_thing_a) {
promise = do_thing_a();
} else {
promise = do_thing_b();
}
promise.then(more_code);
解决方案1
const waitFor = should_do_thing_a ? do_thing_a() : do_thing_b();
waitFor.then(...).catch(...)
解决方案2
let waitFor = Promise.resolve();
if (do_thing_a) {
waitFor = do_thing_a();
} else {
waitFor = do_thing_b();
}
waitFor.then(...).catch(...);
与这里的其他答案类似,但您可以自行执行异步并稍微清理条件
(异步()=>{
const应该做什么事
const do_thing_a=函数(){
返回新承诺(功能(解决、拒绝){
解析('a')
})
}
const do_thing_b=函数(){
返回新承诺(功能(解决、拒绝){
解析('b')
})
}
const result=(应该做某事吗?)等待做某事()等待做某事
console.log(结果)
})()
我的方法是将if检查放入另一个返回承诺的函数中。通过解析if-else语句中的其他函数调用来解析承诺
例如:
function performCheck(condition) {
var defer = $q.defer();
if (condition) {
doThingA().then(function(response) {
defer.resolve(response);
});
} else {
doThingB().then(function(response) {
defer.resolve(response)
});
}
return defer.promise;
}
performCheck(condition).then(function(response) {
//Do more code.
});
在我看来,我更喜欢这种方法,因为这个函数现在可以在多个地方使用,在这些地方您可以检查条件,减少代码重复,并且更容易遵循
您可以使用
function performCheck(condition) {
var defer = $q.defer();
var doThisThing = condition ? doThingA : doThingB;
doThisThing().then(function (response) {
defer.resolve(response);
});
return defer.promise;
}
performCheck(condition).then(function(response) {
//Do more code.
});
如果您被原始承诺所困扰,无法使用
async/await
(使用babel/typescript等,您通常不会遇到问题),那么以下内容比将承诺存储在变量中要优雅一些:
function something() {
return Promise.resolve()
.then(() => {
if (should_do_thing_a) {
return do_thing_a();
}
else if (should_do_thing_b) {
return do_thing_b();
}
})
.then(some_more_code);
}
请注意,当您开始使用承诺时,您的函数应该始终返回其他函数可以使用的承诺。让异步操作没有任何处理方法意味着糟糕的事情,尤其是在错误处理方面
从更一般的意义上讲,这意味着当您使用承诺时,更多的代码被“提升”执行并作为承诺返回。我想如何改进其他答案:
- 保持它干净和简单
- 没有多余的变量
- 尽快归还承诺
- 在js中,我们使用camelCase
- 将其放入函数中并命名该函数以保持其可读性
- 让
执行然后
,这样在事情完成后调用它moreCode
简单的工作示例: 它在中定义的范围必须是async
const createUser = async (data) => {
if (await isUsernameTaken(username)) { return 'username-taken' }
}
IsUsernameTake函数:
const isUsernameTaken = async (username) => {
const request = await API.SomeRequest
return !request.isEmpty
}
async/await
要求定义时使用async
function@guest271314确实如此,但由于OP在他的代码段中没有包含函数定义,所以我将其省略了。我将编辑帖子以包含它。async/await
不起作用。当我试图定义async func(){…}
@ewok async/await仅在较新版本的javascript中可用时,我得到了一个SyntaxError:Unexpected标识符。如果此代码在浏览器中运行,则必须单独使用Promissions,或使用transpiler(babel/typescript/等)。如果您使用的是node,我相信async/await可以在任何7+版本中工作。嗯?为什么您在等待条件函数而不是函数do\u thing\u a
和do\u thing\u b
?shoud\u do\u thing\u a
是表示承诺的变量,否则问题中的代码就没有问题。应该做什么
代表承诺吗?不。应该做什么
只是一个简单的检查,那么问题中的代码有什么问题吗?在承诺解决之前,第一个代码块将执行//更多的代码
。第二个块将正常工作,但在读取时很难遵循控制流。请参阅更新的帖子。虽然还不完全清楚你所说的“阅读时很难遵循控制流程”是什么意思。more\u code()
调用是否返回一个Promise
?您的观点是正确的,但您的代码看起来很难看。我帮你清理了。(太糟糕了,你不能在注释中有多行,现在我的格式已经消失了)函数doTheThing(){if(shouldDoA)返回doThingA(),else返回doThingB()}doTheThing()。然后(moreCode)
我在另一个答案中发布了它,所以这一点会更好一些。
function something() {
return Promise.resolve()
.then(() => {
if (should_do_thing_a) {
return do_thing_a();
}
else if (should_do_thing_b) {
return do_thing_b();
}
})
.then(some_more_code);
}
function doTheThing () {
if (shouldDoA) return doThingA()
else return doThingB()
}
doTheThing().then(moreCode)
const createUser = async (data) => {
if (await isUsernameTaken(username)) { return 'username-taken' }
}
const isUsernameTaken = async (username) => {
const request = await API.SomeRequest
return !request.isEmpty
}