在此示例中,我们读取文件1并将其写入output 文件 。稍后,我们读取文件2并将其再次附加到output文件 。如你所见,writeFile promise返回文件的内容,你可以在下一个then子句中使用它 。
如何链接多个条件承诺?你可能想要跳过 Promise 链上的特定步骤 。有两种方法可以做到这一点 。
const a = () => new Promise((resolve) => setTimeout(() => { console.log('a'), resolve() }, 1e3));const b = () => new Promise((resolve) => setTimeout(() => { console.log('b'), resolve() }, 2e3));const c = () => new Promise((resolve) => setTimeout(() => { console.log('c'), resolve() }, 3e3));const d = () => new Promise((resolve) => setTimeout(() => { console.log('d'), resolve() }, 4e3));const shouldExecA = true;const shouldExecB = false;const shouldExecC = false;const shouldExecD = true;Promise.resolve() .then(() => shouldExecA && a()) .then(() => shouldExecB && b()) .then(() => shouldExecC && c()) .then(() => shouldExecD && d()) .then(() => console.log('done'))
如果你运行该代码示例,你会注意到只有a和d被按预期执行 。
另一种方法是创建一个链,然后仅在以下情况下添加它们:
const chain = Promise.resolve();if (shouldExecA) chain = chain.then(a);if (shouldExecB) chain = chain.then(b);if (shouldExecC) chain = chain.then(c);if (shouldExecD) chain = chain.then(d);chain .then(() => console.log('done'));
如何限制并行 Promise?要做到这一点,我们需要以某种方式限制Promise.all 。
假设你有许多并发请求要执行 。如果使用 Promise.all 是不好的(特别是在API受到速率限制时) 。因此,我们需要一个方法来限制 Promise 个数,我们称其为promiseAllThrottled 。
// simulate 10 async tasks that takes 5 seconds to complete.const requests = Array(10) .fill() .map((_, i) => () => new Promise((resolve => setTimeout(() => { console.log(`exec'ing task #${i}`), resolve(`task #${i}`); }, 5000))));promiseAllThrottled(requests, { concurrency: 3 }) .then(console.log) .catch(error => console.error('Oops something went wrong', error));
输出应该是这样的:
文章插图
以上代码将并发限制为并行执行的3个任务 。
实现promiseAllThrottled 一种方法是使用Promise.race来限制给定时间的活动任务数量 。
/** * Similar to Promise.all but a concurrency limit * * @param {Array} iterable Array of functions that returns a promise * @param {Object} concurrency max number of parallel promises running */function promiseAllThrottled(iterable, { concurrency = 3 } = {}) { const promises = []; function enqueue(current = 0, queue = []) { // return if done if (current === iterable.length) { return Promise.resolve(); } // take one promise from collection const promise = iterable[current]; const activatedPromise = promise(); // add promise to the final result array promises.push(activatedPromise); // add current activated promise to queue and remove it when done const autoRemovePromise = activatedPromise.then(() => { // remove promise from the queue when done return queue.splice(queue.indexOf(autoRemovePromise), 1); }); // add promise to the queue queue.push(autoRemovePromise); // if queue length >= concurrency, wait for one promise to finish before adding more. const readyForMore = queue.length < concurrency ? Promise.resolve() : Promise.race(queue); return readyForMore.then(() => enqueue(current + 1, queue)); } return enqueue() .then(() => Promise.all(promises));}
推荐阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 经期喝枸杞茶可以吗,经期能喝菊花茶吗,经期应该避免喝菊花茶
- 进故宫旅游应该先从什么地方进 游故宫要注意的事情是什么
- 喝茶应该配什么茶点,个茶壶配应该配几个茶杯
- 口腔溃疡应该吃什么好 口腔溃疡药膳调理食疗方
- 女生单身戒指应该戴在哪个手指
- 神经性厌食
- 青少年体育运动应该注意什么
- 出现虚胖应该如何减肥?
- 运动健身计划应该怎么实施?
- 高考语文最后阶段应该如何冲刺提分