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

一个接一个(即按顺序)解决promise?

季炯
2023-03-14

考虑以下以串行/顺序方式读取文件数组的代码。readfiles返回一个promise,该promise仅在按顺序读取所有文件后才解析。

var readFile = function(file) {
  ... // Returns a promise.
};

var readFiles = function(files) {
  return new Promise((resolve, reject) => {
    var readSequential = function(index) {
      if (index >= files.length) {
        resolve();
      } else {
        readFile(files[index]).then(function() {
          readSequential(index + 1);
        }).catch(reject);
      }
    };

    readSequential(0); // Start with the first file!
  });
};

上面的代码可以工作,但我不喜欢必须为事情按顺序发生而做递归。有没有更简单的方法可以重写这段代码,使我不必使用我怪异的readsequential函数?

最初,我尝试使用promise.all,但这导致所有readfile调用并发发生,这不是我想要的:

var readFiles = function(files) {
  return Promise.all(files.map(function(file) {
    return readFile(file);
  }));
};

共有1个答案

贝洲
2023-03-14

更新2017:如果环境支持的话,我会使用异步功能:

async function readFiles(files) {
  for(const file of files) {
    await readFile(file);
  }
};

如果您愿意,可以延迟读取文件,直到使用异步生成器(如果您的环境支持它)需要它们:

async function* readFiles(files) {
  for(const file of files) {
    yield await readFile(file);
  }
};

更新:再三考虑--我可能会使用for循环来代替:

var readFiles = function(files) {
  var p = Promise.resolve(); // Q() in q

  files.forEach(file =>
      p = p.then(() => readFile(file)); 
  );
  return p;
};

或者更紧凑,使用reduce:

var readFiles = function(files) {
  return files.reduce((p, file) => {
     return p.then(() => readFile(file));
  }, Promise.resolve()); // initial
};

在其他promise库(如when和Bluebird)中,您有用于此的实用程序方法。

例如,蓝鸟将是:

var Promise = require("bluebird");
var fs = Promise.promisifyAll(require("fs"));

var readAll = Promise.resolve(files).map(fs.readFileAsync,{concurrency: 1 });
// if the order matters, you can use Promise.each instead and omit concurrency param

readAll.then(function(allFileContents){
    // do stuff to read files.
});

虽然今天真的没有理由不使用异步await。

 类似资料:
  • 问题内容: 考虑以下以串行/顺序方式读取文件数组的代码。返回一个promise,仅当依次读取所有文件后,promise才会解析。 上面的代码有效,但是我不喜欢必须递归使事情顺序发生。有没有更简单的方法可以重写此代码,这样我就不必使用怪异的函数了? 最初我尝试使用,但是这导致所有调用同时发生,这 不是 我想要的: 问题答案: 2017年更新 :如果环境支持,我将使用异步功能: 如果需要,可以使用异步

  • 假设我在Hadoop环境中资源有限,我不想安排长时间运行的作业(即需要几天时间才能完成)。我正在分析大量过去的时间序列数据。我想安排一次需要一天数据的mapreduce作业(这需要一个小时来处理)。 那么,我如何安排,使新的工作提交后,前一个工作完成?

  • 我正在运行一个单节点集群并处理timeseries数据。我有一组MapReduce作业从客户端应用程序定期运行(使用Quartz crontrigger)。例如, 一切都很好。但是有时,可以同时触发多个作业,例如在凌晨00:00触发job1、job2、job3。即使设置了作业优先级,由于可用的映射槽,这些作业被发现是并行执行的。因此,对于低优先级作业,一些输入数据被遗漏了。

  • 我知道有很多关于这个的话题,但是我找不到解决我的问题的方法。我知道如果我在hibernate中使用“不同”和“order by”,order by中的列必须在选择子句中。其他文章只是说该列必须在选择中,但是我还没有找到一个示例来实现这一点。 这是我的班级: 我的(不工作)查询: 例如,如果我按标题排序,它是有效的。我试图在select子句中设置学名: 但是然后hibernate抱怨查询的返回类型不

  • 本文向大家介绍解决Django一个表单对应多个按钮的问题,包括了解决Django一个表单对应多个按钮的问题的使用技巧和注意事项,需要的朋友参考一下 需求: 在django中,有时候我们需要在一个表单中设置多个按钮实现不同的功能。 解决方法: 为不同按钮添加不同name属性,然后再后台判断name值。python2环境下,例如: 我们的表单头 我们的按键,比如实现删除和更新 然后通过不同的name实