当前位置: 首页 > 知识库问答 >
问题:

有没有办法同步化解一个promise?(或一个可供选择的库)

秦皓君
2023-03-14

我有一个用于验证字符串的方法,我希望该方法返回一个承诺,因为正在运行的验证可能是异步的。然而,我遇到的问题是性能问题,我希望在可能的情况下在相同的事件循环中解决Promission(例如:当没有异步验证要做时),但我希望接口保持一致(例如:始终返回Promission)。

下面的简化代码示例说明了我正在尝试的操作,但是它会导致前面提到的性能损失,因为即使可以同步执行验证,它仍然等待下一个事件循环来处理结果。

在我的特定用例中,这种性能损失太高了。

下面是我正在做的一个简化的(最小的)示例

// Array containing validation methods
const validations = [
  (value) => true, // Some validation would happen here
];
// Array containing asynchronous validation methods
const asyncValidations = []; // No async validations (but there could be)
const validate(value){
  // Run synchronous validations
  try {
    validations.forEach(validation => validation(value));
  catch(error){
    // Synchronous validation failed
    return Promise.reject();
  }
  if(asyncValidations){
    return Promise.all(asyncValidations.map(validation => validation(value));
  }
  // Otherwise return a resolved promise (to provide a consistent interface)
  return Promise.resolve(); // Synchronous validation passed 
}

// Example call
validate('test').then(() => {
  // Always asynchronously called
});

共有2个答案

水麒
2023-03-14

承诺异步解析的原因是它们不会炸毁堆栈。考虑以下使用承诺的堆栈安全代码。

null

console.time("promises");

let promise = Promise.resolve(0);

for (let i = 0; i < 1e7; i++) promise = promise.then(x => x + 1);

promise.then(x => {
    console.log(x);
    console.timeEnd("promises");
});
杜弘伟
2023-03-14

你提到了两件不同的事情:

>

  • 我希望接口保持一致

    [我想]永远回报一个承诺

    如果您希望避免异步行为(如果不需要的话),您可以这样做并保持API的一致性。但是你不能做的是“总是返回一个承诺”,因为不可能“同步解决一个承诺”。

    您的代码当前返回一个承诺,该承诺在不需要异步验证时被解析:

    // Otherwise return a resolved promise (to provide a consistent interface)
    return Promise.resolve(); // Synchronous validation passed
    

    您可以用以下代码替换该代码:

    return {then: cb => cb()};
    

    注意,这只是返回一个“thenable”的对象文字(即它有一个then方法),并将同步执行您传递给它的任何回调。但是,它并不回报一个承诺。

    您还可以通过实现then方法和/或catch方法的可选onrejected参数来扩展这种方法。

  •  类似资料:
    • 问题内容: 由于某些性能原因,我试图找到一种仅选择所选节点中同级节点的方法。例如, 如果选择了inner1节点,是否可以访问其兄弟节点? 问题答案: 好吧…确定…先拜访父母,再拜访孩子。 或者…使用jQuery: 编辑:Cletus一如既往地鼓舞人心。 我进一步挖掘。这就是jQuery本质上如何获得兄弟姐妹的方式:

    • 问题内容: 根据MDN 文档: 该 方法冻结对象:即,防止向其添加新属性;防止现有属性被删除;并防止更改现有属性或其可枚举性,可配置性或可写性。本质上,对象实际上是不可变的。该方法返回被冻结的对象。 我期望在某个日期调用冻结会阻止对该日期进行更改,但是它似乎没有用。这是我正在做的(运行Node.js v5.3.0): 我本以为调用会失败或什么都不做。任何想法如何冻结日期? 问题答案: 有没有办法O

    • 问题内容: 我写了一个查询来查找3月至4月美国10个最繁忙的机场。它产生所需的输出,但是我想尝试进一步优化它。 是否有任何适用于查询的HiveQL特定优化? 是适用在这里吗?我是Hive的新手,现在这是我提出的最短的查询。 表列如下: 飞机场 Flights_stats 问题答案: 按机场(内部联接)过滤,并在UNION ALL之前进行聚合,以减少传递到最终聚合简化程序的数据集。具有UNION A

    • 问题内容: 我想根据一个简单的标准更新一组行,并获取已更改的PK列表。我以为我可以做这样的事情,但担心可能出现的并发问题: 如果将其包装在事务中,是否会发生任何并发问题?还是有更好的方法来做到这一点? 问题答案: 考虑查看OUTPUT子句:

    • 有没有办法(一步一步)在M1 Mac上设置PyCharm?我正在寻找一些一步一步地如何克服口译员的错误。还有一个错误消息发生在我的简单Hello world打印中。 “进程结束,退出代码137(被信号9:SIGKILL中断)”

    • 我有一个需求,我想找到运行的jar中的jar的路径。假设有一个名为example-1.0.0.jar的罐子在一个名为main-1.0.0.jar.的运行罐子里,我想知道运行罐子里存在的罐子的路径。 编辑1:例如,jar是项目中的一个依赖项。例如,假设我的项目中有一个log4j依赖项,我想知道log4j jar在类中的路径。我怎样才能找到路?