如何在 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.resolveES6上可以提出直接落入成功案例的解决方案,但我想知道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