You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
			
				
					53 lines
				
				1.2 KiB
			
		
		
			
		
	
	
					53 lines
				
				1.2 KiB
			| 
								 
											4 years ago
										 
									 | 
							
								'use strict';
							 | 
						||
| 
								 | 
							
								const pLimit = require('p-limit');
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class EndError extends Error {
							 | 
						||
| 
								 | 
							
									constructor(value) {
							 | 
						||
| 
								 | 
							
										super();
							 | 
						||
| 
								 | 
							
										this.value = value;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// The input can also be a promise, so we await it
							 | 
						||
| 
								 | 
							
								const testElement = async (element, tester) => tester(await element);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// The input can also be a promise, so we `Promise.all()` them both
							 | 
						||
| 
								 | 
							
								const finder = async element => {
							 | 
						||
| 
								 | 
							
									const values = await Promise.all(element);
							 | 
						||
| 
								 | 
							
									if (values[1] === true) {
							 | 
						||
| 
								 | 
							
										throw new EndError(values[0]);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									return false;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const pLocate = async (iterable, tester, options) => {
							 | 
						||
| 
								 | 
							
									options = {
							 | 
						||
| 
								 | 
							
										concurrency: Infinity,
							 | 
						||
| 
								 | 
							
										preserveOrder: true,
							 | 
						||
| 
								 | 
							
										...options
							 | 
						||
| 
								 | 
							
									};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									const limit = pLimit(options.concurrency);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									// Start all the promises concurrently with optional limit
							 | 
						||
| 
								 | 
							
									const items = [...iterable].map(element => [element, limit(testElement, element, tester)]);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									// Check the promises either serially or concurrently
							 | 
						||
| 
								 | 
							
									const checkLimit = pLimit(options.preserveOrder ? 1 : Infinity);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									try {
							 | 
						||
| 
								 | 
							
										await Promise.all(items.map(element => checkLimit(finder, element)));
							 | 
						||
| 
								 | 
							
									} catch (error) {
							 | 
						||
| 
								 | 
							
										if (error instanceof EndError) {
							 | 
						||
| 
								 | 
							
											return error.value;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										throw error;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								module.exports = pLocate;
							 | 
						||
| 
								 | 
							
								// TODO: Remove this for the next major release
							 | 
						||
| 
								 | 
							
								module.exports.default = pLocate;
							 |