当前位置: 首页 > 知识库问答 >
问题:

异步函数与返回

陈项禹
2023-03-14

更新

我已经读了十几篇关于这个话题的文章,但没有一篇涉及到这个基本问题。我将在本文末尾列出一个参考资料部分。

原始帖子

我对async函数的理解是,它返回一个promise。

MDN文档:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function

在我的程序中,我可以编写如下内容:

function testPromise() {
  return new Promise((resolve, reject) => {
    // DO WORK
    reject() // IF WORK FAILS
    resolve() // IF WORK IS SUCCESSFUL        
  })
}

async function mainFunction() {
  let variable
  try {
    variable = await testPromise()
  } catch(e) {
    throw e
  }
  return variable
}

我也可以把testPromise写成一个异步函数,并在同一个上下文中等待它。

async function testAsyncFunction() {
  //DO WORK AND THROW ERROR IF THEY OCCUR      
}

async function mainFunction() {
  let variable
  try {
    variable = await testAsyncFunction()
  } catch(e) {
    throw e
  }
  return variable
}

哪种做法被认为是最佳做法?如果我希望创建异步操作,该函数是否使用返回New Promise并在一个异步函数中等待,或者正在等待一个异步函数中的异步函数?

资源

JavaScript ES 2017:学习异步/等待的例子https://codeburst.io/javascript-es-2017-learn-async-await-by-example-48acc58bad65

Javascript — ES8引入async/await函数https://medium.com/@reasoncode/javascript-es8-introduction-async-await-functions-7a471ec7de8a

JavaScript的异步/等待吹走promise的6个原因(教程)https://hackernoon.com/6-reasons-why-javascripts-async-await-blows-promises-away-tutorial-c7ec10518dd9

--------------------------------------------

export default function time_neo4jUpdate({ store, action, change, args, }) {
  return new Promise(async (resolve, reject) => {
    try {
      const {
        thing: { type },
        nonValidatedArgs: { leapYear, root, start, end },
          _neo4j,
          _cypherReducers,
          _neo4jCreateReduce,
          _timetreeSteps: { update }
      } = store.getState()
      let results = []
      for (let i = 0; i < _neo4jCreateReduce.length; i++) {
        const result = await _neo4j.session(
          _neo4jCreateReduce[i],
          _cypherReducers.runQuery(update, i, root, start, end))
        results = [...results, result]
      }
      resolve({
        store,
        action: 'NEO4J_UPDATE',
        change: results,
        args
      })
    } catch (e) {
      const m = `NEO4J TIMETREE UPDATE: Unable to complete the UPDATE step for the timetree. WHAT: ${e}`
      reject(m)
    }
  })
}

----------------------作为异步函数----------------------

export default async function time_neo4jUpdate({ store, action, change, args, }) {
  try {
    const {
      thing: { type },
      nonValidatedArgs: { leapYear, root, start, end },
      _neo4j,
      _cypherReducers,
      _neo4jCreateReduce,
      _timetreeSteps: { update }
    } = store.getState()
    let results = []
    for (let i = 0; i < _neo4jCreateReduce.length; i++) {
      const result = await _neo4j.session(
        _neo4jCreateReduce[i],
        _cypherReducers.runQuery(update, i, root, start, end))
      results = [...results, result]
    }
    return {
      store,
      action: 'NEO4J_UPDATE',
      change: results,
      args
    }
  } catch (e) {
    const m = `NEO4J TIMETREE UPDATE: Unable to complete the UPDATE step for the timetree. WHAT: ${e}`
    throw m
  }
}

共有1个答案

杨飞飙
2023-03-14

即使没有async/wait,您也很少需要使用newpromise()。如果您经常使用它,它通常是一种代码气味。

async/await的全部要点是,它允许您避免许多需要明确使用promise的情况。

因此,如果您的目标环境支持它(Internet Explorer不支持async/await),或者您使用的是transpiler,请继续,并在任何可以使用的地方使用它。这就是它的目的。

请记住,这是毫无意义的:

catch(e) {
    throw e;
}

抓住一个错误只是为了重新抛出它是没有意义的。因此,如果你实际上没有用捕获的错误做任何事情,不要捕获它:

async function testAsyncFunction() {
  //DO WORK AND THROW ERROR IF THEY OCCUR
  return value
}

编辑:既然你已经提供了一个代码的例子,我可以更确定地回答:如果你的函数是基于现有的promise,那么无论如何,使用async/wait都是好的,你通常不应该使用new Promise()

export default async function time_neo4jUpdate({
    store,
    action,
    change,
    args,
  }) {
    try {
      const {
        thing: {
          type
        },
        nonValidatedArgs: {
          leapYear,
          root,
          start,
          end
          },
          _neo4j,
          _cypherReducers,
          _neo4jCreateReduce,
          _timetreeSteps: {
            update
        }
      } = store.getState()

      const results = await _neo4jCreateReduce.reduce(async function (acc, el) {
        const result = await _neo4j.session(
          el,
          _cypherReducers.runQuery(
            update,
            i,
            root,
            start,
            end
          )
        )

        return [...(await acc), result]
      }, []);

      return {
        store,
        action: 'NEO4J_UPDATE',
        change: results,
        args
      };
    } catch (e) {
      const m = `NEO4J TIMETREE UPDATE: Unable to complete the UPDATE step for the timetree. WHAT: ${e}`
      throw m;
    }
}
 类似资料:
  • 问题内容: 如何从异步函数返回值?我试图喜欢这个 它给了我, 问题答案: 您不能超出范围。为了获得预期的结果,您应该将其包装到异步IIFE中,即 样品。 有关更多信息 由于返回一个Promise,因此可以将其省略,如下所示: 然后像以前一样做

  • 问题内容: 就像一个人在这里问到但他的解决方案是调用其他函数 …我想知道是否有可能拥有一个不调用a的函数第二个功能基于异步请求的响应,但仅当异步请求响应时。 可能是这样的: 不调用另一个函数,这有可能吗? 我要实现的目标是拥有一个可以用一些参数调用的函数,该函数将返回异步Web服务(如FB)的响应。 问题答案: 简而言之,没有。您不能让异步函数同步返回有意义的值,因为该值当时不存在(因为它是在后台

  • 我真的需要温习一下我的异步等待和promise。我想要一些建议。 我正在对firebase firestore进行异步函数调用。函数应根据单个输入参数返回字符串。 该功能适用于1-1用户聊天。该功能是创建聊天/查找现有聊天,并返回其ID。 现在,我得到的作为返回值的和不知道为什么。除了返回之外,该函数还能正常工作。 我有两个功能。一个是React类组件生命周期方法,另一个是我的firebase异步

  • 问题内容: 如何从异步函数返回值?我试图喜欢这个 它给了我, 问题答案: 您不能超出范围。为了获得预期的结果,您应该将其包装到异步IIFE中,即 样品。 有关更多信息 由于返回一个Promise,因此可以将其省略,如下所示: 然后像以前一样做

  • 它必须是基本的,但请帮助我理解为什么这不起作用。 当我编写一个普通的arrow函数并返回jsx时,它就工作了。但是,当我使用async/await请求和相同的arrow函数返回jsx时,它失败了。 编辑: 实际上,我必须在列表视图中显示用户的配置文件图像。所以,我调用这个函数来检索我的块中相应用户的图像 这很有效 但事实并非如此

  • 我在一个函数中有这样的代码块: 它获取一些数据,然后对数据运行验证()。 但是,我对数据的验证实际上也是异步的,因为它是根据一个json模式来验证数据的,而json模式位于一个独立的json文件中,所以它必须首先读取该文件。 我使用了一个承诺来读取文件内容,然后进行验证: 如何编辑此问题中的顶部代码块以解释if语句()中的异步函数?