如何摆脱异步功能?

时间:2018-12-03 12:21:10

标签: javascript async-await nightwatch.js

假设我有以下代码:

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

但这仍然返回了诺言

我不能在 myFunction 中使用。然后,我需要 foobar 返回结果变量而不是promise。

问题是 myFunction 是一个异步函数,它将返回一个promise,但是它应该返回undefined,我需要摆脱 myFunction 中的异步。

编辑:正如Sebastian Speitel所说,我要转换 myFunction 进行同步

编辑2:对于Shilly,我正在使用Nightwatch进行end2end测试,如果函数执行中没有错误,nightwatch将调用 myFunction(),如果出现错误,它将完美运行然后守夜人的虚拟机将永远运行而不是停止,如果被调用函数是异步的,则会发生此问题。

5 个答案:

答案 0 :(得分:2)

To change an asynchronous function into a normal synchronous function you simply have to drop the async keyword and as a result all await keywords within that function.

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

// becomes

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

You should however keep one simple rule in mind.

  1. You can't change a asynchronous function into a synchronous function if the return value depends on the value(s) of the resolved promise(s).

This means that functions that handle promises inside their body, but from whom the return value doesn't depend on those resolved promises are perfectly fine as synchronous functions. In most other scenarios you can't drop the asynchronous behaviour.

The following code gives you an example for your situation, assuming the return value of myFunction doesn't depend on the resolved promise.

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

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

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

If you want to learn more about promises I suggest checking out the promises guide and the async/await page.

答案 1 :(得分:1)

Have you looked into using .executeAsync() and then having the promise call the .done() callback? That way it should be possible to wrap foobar and just keep either the async or any .then() calls inside that wrapper.

My nightwatch knowledge is very stale, but maybe something like:

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

or:

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

答案 2 :(得分:0)

任何标有async的函数都将返回Promise。这个:

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

返回的Promise为7。这完全独立于调用foobar的函数是否为async,或者在调用它时是否使用await

因此,您的问题不仅仅在于myFunctionfoobar是否使用async强制其始终返回Promise。

现在,说,您可能无法实现想要的目标。 Async-Await 只是诺言的语法糖。您要尝试的是return a synchronous value from an asynchronous operation,而这在javascript中基本上是禁止的。

答案 3 :(得分:0)

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

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

相反,我建议您仅使用await,如您的第一个代码示例一样,并使函数保持异步状态,这不会损害您的逻辑。

答案 4 :(得分:0)

Check this out

    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)