Javascript 在 if/else 中处理 promise

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/47083855/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 03:43:49  来源:igfitidea点击:

Working with promises inside an if/else

javascriptpromise

提问by ewok

I have a conditional statement in which I need to perform one of two operations, then continue after whichever operation has resolved. So my code currently looks as follows:

我有一个条件语句,我需要在其中执行两个操作之一,然后在任何一个操作解决后继续。所以我的代码目前如下所示:

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

The issue is that both do_thing_aand do_thing_breturn promises, and I can't move on until whichever gets executed has resolved. The best way I've come up with to solve this is like this:

问题是do_thing_a和 都do_thing_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)
}

I don't like this structure. It's difficult to follow because you need to jump around to find where more_codeis defined (imagine I have this type of control flow in several locations), rather than simply being able to continue reading.

我不喜欢这种结构。很难理解,因为您需要四处寻找more_code定义的位置(想象一下我在几个位置都有这种类型的控制流),而不是简单地能够继续阅读。

Is there a better way to deal with this type of thing in javascript?

有没有更好的方法来处理 javascript 中的这种类型的事情?

采纳答案by CRice

If you can use async/await

如果你可以使用 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()
}

Or if you can't, use then():

或者,如果您不能,请使用then()

var more_code = function () { 
    // more code
}

var do_thing;
if (shoud_do_thing_a) {
  do_thing = do_thing_a()
} else {
  do_thing = do_thing_b()
}

do_thing.then(more_code)

回答by Madara's Ghost

If you're stuck with raw Promises and can't use async/await(You usually should have no trouble, what with babel/typescript etc), the following is a bit more elegant than storing the promise in a variable:

如果您坚持使用原始 Promise 并且无法使用async/await(您通常应该没有问题,使用 babel/typescript 等),以下比将 Promise 存储在变量中更优雅:

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);
}

Note that when you start working with Promises, your functions should always return a Promise that other functions can work with. Leaving an asynchronous action without any way to handle it means bad things, especially when it comes to error handling.

请注意,当您开始使用 Promise 时,您的函数应始终返回其他函数可以使用的 Promise。离开异步操作而没有任何方法来处理它意味着不好的事情,尤其是在错误处理方面。

In a more general sense, it means that when you use Promises, more of your code is "uplifted" into being executed and returned as Promises.

从更一般的意义上讲,这意味着当您使用 Promises 时,您的更多代码被“提升”为执行并作为 Promises 返回。

回答by ThaJay

How I want to improve on other answers:

我想如何改进其他答案:

  • keep it clean and simple
  • no unneeded variables
  • return promise asap
  • in js we use camelCase
  • put it in a function and name that function to keep it readable
  • let thenexecute moreCodeso it's called after the thing is done.
  • 保持干净和简单
  • 没有不需要的变量
  • 尽快回复承诺
  • 在js中我们使用camelCase
  • 将它放在一个函数中并命名该函数以使其可读
  • then执行,moreCode以便在事情完成后调用它。


function doTheThing () {
  if (shouldDoA) return doThingA()
  else return doThingB()
}

doTheThing().then(moreCode)

回答by Oliver Dixon

Simple working example:

简单的工作示例:

The scope it's defined in must be async.

它定义的范围必须是async

const createUser = async (data) => {
   if (await isUsernameTaken(username)) { return 'username-taken' }
}

The isUsernameTaken func:

isUsernameTaken 函数:

const isUsernameTaken = async (username) => {
    const request = await API.SomeRequest
    return !request.isEmpty
}

回答by dzm

Similar to other answers here, but you can self execute the async and clean up the condition a bit.

与此处的其他答案类似,但您可以自行执行异步并稍微清理一下条件。

(async () => {
  const should_do_thing_a = true

  const do_thing_a = function() {
    return new Promise(function(resolve, reject) {
      resolve('a')
    })
  }

  const do_thing_b = function() {
    return new Promise(function(resolve, reject) {
      resolve('b')
    })
  }

  const result = (should_do_thing_a) ? await do_thing_a() : await do_thing_b()

  console.log(result)

})()

回答by CrazyJane

The way I would do it would be to put the if check into another function that returns a promise. The promise gets resolved with the resolve of the other function calls in the if-else statement.

我这样做的方法是将 if 检查放入另一个返回承诺的函数中。承诺通过 if-else 语句中其他函数调用的解析得到解析。

Example:

例子:

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.
});

In my opinion, I would prefer this method because this function can now be used in multiple places where you have a check on the condition, reducing code duplication, and it is easier to follow.

在我看来,我更喜欢这种方法,因为这个函数现在可以用于多个检查条件的地方,减少代码重复,并且更容易遵循。

You could reduce this down further with

你可以进一步减少这个

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.
});

回答by Nachshon Schwartz

Save the promise and add the then after the if statement:

保存承诺并在 if 语句之后添加 then:

var promise;

if (shoud_do_thing_a) {
  promise = do_thing_a();
} else {
  promise = do_thing_b();
}

promise.then(more_code);

回答by Peter

var promise = shoud_do_thing_a? do_thing_a: do_thing_b

promise().then(function () {
// more code    
})

回答by guest271314

You can use async/await

您可以使用 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
}

回答by Jose Mato

more_code = miFunc() => return new Promise((resolve, reject) => ... });

Solution 1

解决方案1

const waitFor = should_do_thing_a ? do_thing_a() : do_thing_b();
waitFor.then(...).catch(...)

Solution 2

解决方案2

let waitFor = Promise.resolve();

if (do_thing_a) {
    waitFor = do_thing_a();
} else {
    waitFor = do_thing_b();
}

waitFor.then(...).catch(...);