如何摆脱函数中的异步?

How to get rid of async in function?

假设我有这个代码:

const myFunction = async => {
  const result = await foobar()
}

const foobar = async () => {
  const result = {}
  result.foo = await foo()
  result.bar = await bar()
  return result
}

我想要这个:

const myFunction = () => {
  const result = foobar()
}

我试着像这样包装 foobar

const foobar = async () => {
  return (async () => {
    const result = {}
    result.foo = await foo()
    result.bar = await bar()
    return result
  })()
}

但这仍然是return一个承诺

我不能在 myFunction 中使用 .then,我需要 foobar returns 结果变量而不是承诺。

问题是 myFunction 是一个异步函数,它将 return 一个 promise 但它应该 return undefine 我需要摆脱异步在 myFunction.

编辑:正如 Sebastian Speitel 所说,我想将 myFunction 转换为 sync

编辑 2:致 Shilly,我正在使用 nightwatch 进行端到端测试,nightwatch 将调用 myFunction() 如果函数的执行没有错误,它将 运行 完美,如果出现错误,nightwatch 的虚拟机将 运行 永远停止,如果被调用的函数是异步的,就会出现此问题。

任何标有 async 的函数都会 return 一个 Promise。这个:

const foobar = async () => {
  return 7;
}

return 将是 7 的 Promise。这完全独立于调用 foobar 的函数是否为 async,或是否使用 await调用时。

所以,你的问题不(仅)与 myFunction 有关:是 foobar 使用 async 这迫使它总是 return 一个 Promise。

现在说,你可能达不到你想要的。 Async-Await 只是 promises 的语法糖。您正在尝试的是 return a synchronous value from an asynchronous operation,而这在 javascript.

中基本上是被禁止的

您在这里缺少对代码的同步和异步性质之间非常重要的理解。

并不是每个异步函数都可以转换为同步函数。您可以使用回调模式代替 await/async,但我怀疑这对您是否有用。

相反,我建议您只使用 await,就像在您的第一个代码示例中一样,并将函数保留为异步,这不会损害您的逻辑。

您是否考虑过使用 .executeAsync() 然后让 promise 调用 .done() 回调?这样应该可以包装 foobar 并在该包装器中保留异步或任何 .then() 调用。

我的守夜人知识很陈旧,但可能是这样的:

() => {
  client.executeAsync(( data, done ) => {
    const result = await foobar();
    done( result );
  });
};

或:

  () => {
    client.executeAsync(( data, done ) => foobar().then( result => done( result )));
  };

要将异步函数更改为普通的同步函数,您只需删除 async 关键字,结果是该函数中的所有 await 个关键字。

const myFunction = async () => {
    const result = await foobar();
    // ...
    return 'value';
};

// becomes

const myFunction = () => {
    const result = foobar();
    // ...
    return 'value';
};

但是,您应该记住一个简单的规则。

  1. 如果 return 值取决于已解析承诺的值,则不能将异步函数更改为同步函数。

这意味着在其主体内处理 promises 的函数,但 return 值不依赖于那些已解决的 promises 的函数作为同步函数是完美的。在大多数其他情况下,您不能放弃异步行为。

以下代码为您提供了一个示例,假设 myFunction 的 return 值不依赖于已解决的承诺。

const myFunction = () => {
    const result = foobar();

    result.then(data => doSomethingElse(data))
          .catch(error => console.error(error));

    return 'some value not dependent on the promise result';
};

如果您想了解有关承诺的更多信息,我建议您查看 promises guide and the async/await 页面。

看看这个

    function foo(){
      return 'foo'
    }
    function bar(){
      return 'bar'
    }
    const foobar = () => {
        return new Promise((resolve)=>{
          let result = {}
          result.foo = foo()
          result.bar = bar()
          return resolve(result)
        })
    }

    const myFunction = () => {
      const result = foobar()
      let response = {}
      result.then(val=>{
        response = Object.assign({}, val);
        return response
      });
    }

    var test = myFunction()
    console.log(test)