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
}