返回正在进行的异步调用的承诺

时间:2018-11-23 14:15:17

标签: javascript node.js asynchronous es6-promise

我正在尝试同时启动许多异步功能。他们中的一些人打了一些http电话,我显然不想多次打相同的电话。因此,如何使用ES6 Promises做到这一点,如果没有,您将建议使用什么机制来处理这种情况。

问题示例:

const func1 = () => async1();

const func2 = () => async2().then(async1);

return Promise.all([func1(), func2()]);

async1和async2是返回Promises的异步函数。 问题是如何处理三种情况:

  • func1和func2同时启动async1
  • func2启动async1,而async1是func2中正在进行的异步调用
  • async1在func1已解决async1之后由func2启动

最后一种情况是我现在打过的唯一电话,以防止同一电话多次发出。

2 个答案:

答案 0 :(得分:1)

您可以随时重用promise对象,因此,如果您在第一次调用请求promise时存储了请求promise,则可以在后续调用中返回存储的promise,并避免对同一资源进行多次请求

const async1 = (() => {
  let promise;

  return (arg) => {
    console.log(arg, ' = ', promise ? 'Cached request' : 'New request');
    promise = promise || new Promise((res) => setTimeout(res, 500));
    return promise.then(()=>arg);
  }

})()

Promise.all([async1(1),async1(2)]).then(res=>console.log(res))

答案 1 :(得分:0)

如果我理解正确,则希望确保示例中的async1不会被调用两次。

实现这一目标的容易程度(很低)是memoization

用lodash的_.memoize()说吧

const async1 = _.memoize(async1, () => 1)
// wrapping func1 and func2 is not actually required in this case
const func1 = _.memoize(() => async1()); 
const func2 = _.memoize(() => async2().then(async1));
return Promise.all([func1(), func2()]);

请注意,因为您无法动态地从已记忆的实现切换到_un_memoized的实现。

[UPD],因为备忘录依赖于传递的参数,因此您可能需要传递resolver回调。假设您的情况async1可能有零个参数,或者来自先前的promise(在.then中使用)。所以参数是不同的,但是因为我们知道所有参数都没有关系,所以我们可以传递返回常量作为键(例如'1')的解析器