如何在 JavaScript 中有条件地调用异步函数
How to call asynchronous function conditionally in JavaScript
我想在 JavaScript/ES5 中进行有条件的异步函数调用。
假设我有一个带有函数 myAsyncFunction
的模块 myService
,它在内部执行一些逻辑并且 returns 结果带有如下回调:
myService.myAsyncFunction(param1, param2, (error, success) => {
if (error) {
// handle error
return;
}
// handle success
});
但在某些情况下,我希望它直接落入"handle success"而不需要运行myService.myAsyncFunction
里面的逻辑,这可能需要一些时间和资源。
我想象的最直接的方法是创建一个模仿 myService.myAsyncFunction
的虚拟函数并调用回调而没有错误,如下所示:
var myGenericFunction;
if ( /* I would like to skip unnecessary logic */) {
myGenericFunction = function (param1, param2, callback) {
callback(null);
}
} else {
myGenericFunction = myService.myAsyncFunction;
}
myGenericFunction(param1, param2, (error, success) => {
if (error) {
// handle error
return;
}
// handle success
});
这是我最终得到的,但我想在语法和性能方面应该有更好的方法。你有什么建议吗?
注意:Promise.resolve
ES6上可以提出直接落入成功案例的解决方案,但我想知道ES5的解决方案是什么。
首先,为不支持它的 javascript 环境引入 Promise
polyfill 非常容易。它应该一直工作到 Ecmascript 3。
忽略这一点,如果你有这样的异步函数:
function myAsync(arg1, callback) {
}
但是对于某些值或者arg1
你想立即调用回调,但是你不能改变函数,这样做的合理方法确实是包装它:
function myAsyncWrapped(arg1, callback) {
if (arg1 === SOME_VALUES) {
callback(null, true);
} else {
myAsync(arg1, callback);
}
}
如果您需要为 多个 异步函数执行此操作,则可以概括为:
function asyncWrapper(innerFunction) {
return (arg1, callback) {
if (arg1 === SOME_VALUES) {
callback(null, true);
} else {
innerFunction(arg1, callback);
}
}
}
所以你可以这样称呼它:
myAsyncWrapped = asyncWrapper(myAsync);
我可以想到几种替代方法来滚动您自己的 Promise 实现。
您可以使用现有的,例如 Bluebird - http://bluebirdjs.com/docs/getting-started.html
您还可以使用转译器,例如 Babel,它允许您编写您想要的所有下一代 ES,并在运行前将其转换为 ES5 - https://babeljs.io/docs/en
我想在 JavaScript/ES5 中进行有条件的异步函数调用。
假设我有一个带有函数 myAsyncFunction
的模块 myService
,它在内部执行一些逻辑并且 returns 结果带有如下回调:
myService.myAsyncFunction(param1, param2, (error, success) => {
if (error) {
// handle error
return;
}
// handle success
});
但在某些情况下,我希望它直接落入"handle success"而不需要运行myService.myAsyncFunction
里面的逻辑,这可能需要一些时间和资源。
我想象的最直接的方法是创建一个模仿 myService.myAsyncFunction
的虚拟函数并调用回调而没有错误,如下所示:
var myGenericFunction;
if ( /* I would like to skip unnecessary logic */) {
myGenericFunction = function (param1, param2, callback) {
callback(null);
}
} else {
myGenericFunction = myService.myAsyncFunction;
}
myGenericFunction(param1, param2, (error, success) => {
if (error) {
// handle error
return;
}
// handle success
});
这是我最终得到的,但我想在语法和性能方面应该有更好的方法。你有什么建议吗?
注意:Promise.resolve
ES6上可以提出直接落入成功案例的解决方案,但我想知道ES5的解决方案是什么。
首先,为不支持它的 javascript 环境引入 Promise
polyfill 非常容易。它应该一直工作到 Ecmascript 3。
忽略这一点,如果你有这样的异步函数:
function myAsync(arg1, callback) {
}
但是对于某些值或者arg1
你想立即调用回调,但是你不能改变函数,这样做的合理方法确实是包装它:
function myAsyncWrapped(arg1, callback) {
if (arg1 === SOME_VALUES) {
callback(null, true);
} else {
myAsync(arg1, callback);
}
}
如果您需要为 多个 异步函数执行此操作,则可以概括为:
function asyncWrapper(innerFunction) {
return (arg1, callback) {
if (arg1 === SOME_VALUES) {
callback(null, true);
} else {
innerFunction(arg1, callback);
}
}
}
所以你可以这样称呼它:
myAsyncWrapped = asyncWrapper(myAsync);
我可以想到几种替代方法来滚动您自己的 Promise 实现。
您可以使用现有的,例如 Bluebird - http://bluebirdjs.com/docs/getting-started.html
您还可以使用转译器,例如 Babel,它允许您编写您想要的所有下一代 ES,并在运行前将其转换为 ES5 - https://babeljs.io/docs/en