如何摆脱函数中的异步?
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';
};
但是,您应该记住一个简单的规则。
- 如果 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)
假设我有这个代码:
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';
};
但是,您应该记住一个简单的规则。
- 如果 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)