【问题标题】:How to call asynchronous function conditionally in JavaScript如何在 JavaScript 中有条件地调用异步函数
【发布时间】:2018-09-05 12:42:23
【问题描述】:

我想在 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 解决方案是什么。

【问题讨论】:

  • 我不明白,你要不要使用 Promises?你有 ~2 个选择:使用回调或使用 Promises(也许是 async/await)。请选择一个。无论如何,如果您选择异步方法,则必须始终保持异步。
  • @zero298 不,我不想使用 Promise。我提到它是因为我想让你知道我知道“承诺”的方式,但更喜欢 ES5 解决方案。
  • 所以,我从问题的标题中删除了“承诺”,以免引起混淆,如果这是投反对票的原因。

标签: javascript asynchronous promise conditional ecmascript-5


【解决方案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);

【讨论】:

    【解决方案2】:

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

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

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

    【讨论】:

    • 感谢@mattezell 的建议。无论如何,我仍然在寻找非 Promise 解决方案。
    • 没问题。我认为“所以你可以将这个问题总结为“我如何在 ES5 上使用 Promise.resolve?”这句话可能会给这个问题带来一些混乱。如果没有更好/不同的方法。'。我认为这个假设是“当然有异步,因为它是 JavaScript”——我认为另一个广泛持有的假设是“使用 Promise 比滚动你自己的替代异步实现更干净/更好”。
    • 好的,我还更新了注释以删除“问题摘要”内容,因为问题都在标题上。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-24
    • 2019-02-20
    • 2020-03-09
    • 1970-01-01
    • 1970-01-01
    • 2012-02-25
    相关资源
    最近更新 更多