首页 文章

异步功能与返回新承诺

提问于
浏览
10

UPDATE

我已经阅读了十几篇关于这个主题的文章,其中没有一篇论述这个基本问题 . 我将在本文末尾开始列出资源部分 .

ORIGINAL POST

我对 async 函数的理解是它返回一个承诺 .

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函数,并在同一个上下文中编写 await .

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
}

哪个被认为是最佳做法?如果我希望创建异步操作,该函数是否应该使用 return New Promise 并等待 async 函数或等待 async 函数与 async 函数相同的区别?

RESOURCES

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-introducing-async-await-functions-7a471ec7de8a

JavaScript的Async / Await等待承诺的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)
    }
  })
}

---------------------- AS ASYNC FUNCTION ----------------------

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 回答

  • 4

    即使没有 async / awaityou should very rarely need to use new Promise()的可用性 . 如果你通常是代码味道 .

    async / await 的重点在于它允许您避免很多情况,否则您需要明确地使用promises .

    因此,如果它重新定位(Internet Explorer不支持 async / await ),或者你're using a transpiler, go ahead and use it anywhere you can. That'是什么原因 .

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

    catch(e) {
        throw e;
    }
    

    grab 错误只是为了重新抛出它是没有意义的 . 因此,如果您实际上没有对捕获的错误做任何事情,请不要 grab 它:

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

    Edit: 现在您已经提供了一个代码示例,我可以更加确定地回答:如果您的函数基于现有的承诺,那么无论如何,最好使用 async / await 并且您通常不应该使用 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;
        }
    }
    

相关问题