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

考虑以下以串行/顺序方式读取文件数组的代码。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!

});

};

上面的代码有效,但是我不喜欢必须递归使事情顺序发生。有没有更简单的方法可以重写此代码,这样我就不必使用怪异的readSequential函数了?

最初我尝试使用Promise.all,但是这导致所有readFile调用同时发生,这 不是 我想要的:

var readFiles = function(files) {

return Promise.all(files.map(function(file) {

return readFile(file);

}));

};

回答:

:如果环境支持,我将使用异步功能:

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;

};

或更紧凑,减少:

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.

});

尽管今天确实没有理由 使用异步等待。

以上是 解决承诺一个接一个(即按顺序)? 的全部内容, 来源链接: utcz.com/qa/408595.html

回到顶部