Promise 是 JavaScript 中处理异步操作的常用方法。然而,控制 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! }); };
这段代码使用递归来依次读取文件,但是工作起来可能很有挑战性with.
避免使用 Async/Await 进行递归:
在现代 JavaScript 中,使用 async 函数和 wait 是一个更优雅的解决方案:
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; };
或者,利用 Promise Reduction:
使用 reduce 的更紧凑的解决方案:
var readFiles = function(files) { return files.reduce((p, file) => { return p.then(() => readFile(file)); }, Promise.resolve()); // initial };
库实用程序方法
某些承诺库(例如 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. });
以上是如何按顺序解决 JavaScript Promise?的详细内容。更多信息请关注PHP中文网其他相关文章!