如何在JavaScript中有条件地调用异步函数

时间:2018-09-05 12:42:24

标签: javascript asynchronous promise conditional ecmascript-5

我想在JavaScript / ES5中进行条件异步函数调用。

说我有一个带有功能myService的模块myAsyncFunction,该模块在内部做一些逻辑,并通过如下所示的回调返回结果:

myService.myAsyncFunction(param1, param2, (error, success) => {
    if (error) {
        // handle error
        return;
    }
    // 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
});

这是我最终得到的结果,但是我认为应该在语法和性能方面都存在更好的方法。你有什么建议吗?

注意:ES6上的Promise.resolve可以提出一种解决方案以直接进入成功案例,但我想知道什么是ES5解决方案。

2 个答案:

答案 0 :(得分:1)

首先,在不支持的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);

答案 1 :(得分:0)

我可以想到几种替代方法来滚动自己的Promise实现。

您可以使用现有的设备,例如Bluebird-http://bluebirdjs.com/docs/getting-started.html

您还可以使用诸如Babel之类的编译器,它可以让您编写所需的所有下一代ES,并将其转换为ES5运行前-https://babeljs.io/docs/en