APIJSON icon indicating copy to clipboard operation
APIJSON copied to clipboard

远程函数执行结果如何作为数组条件进行传递

Open zxcwindy opened this issue 1 year ago • 4 comments

Description

postgresql数据库有一列id的类型为uuid,通过以下方式过滤数据库会提示两边类型不匹配的异常:operator does not exist: uuid = character varying

{
...
"id":"e94f8127-1dee-4f12-aefe-34f7fc601231"
....
}

编写了一个函数进行远程函数调用

.....
public Object uuidStr(@NotNull JSONObject current, String uuid) {
		try {
			return UUID.fromString(uuid);
		} catch (Exception e) {
			e.printStackTrace();
			return uuid;
		}
	}
......

可以通过以下方式返回正常结果

{
....
"id()":"uuidStr(e94f8127-1dee-4f12-aefe-34f7fc601231)"
}

现在的问题是,我想实现id in ('e94f8127-1dee-4f12-aefe-34f7fc601231','ebc48f09-47da-4941-88f4-adfdc28db0d0',....)的效果,但是好像没法同时用 "id(){}":[uuidStr(e94f8127-1dee-4f12-aefe-34f7fc601231),uuidStr(ebc48f09-47da-4941-88f4-adfdc28db0d0)..]

请问以上场景该如何实现

zxcwindy avatar Jul 30 '24 03:07 zxcwindy

分步骤,两个键值对先后执行,远程函数需要 key-() 提高优先级

TommyLemon avatar Jul 31 '24 01:07 TommyLemon

另外 PostgreSQL 可以加参数配置字符串传参,适配各种数据库类型,网上查下,可以不用 APIJSON 远程函数

TommyLemon avatar Jul 31 '24 01:07 TommyLemon

Using Remote Function Results as Array Conditions

Overview

When working with remote function execution, you often need to use the returned results as conditions in array operations. Here are several approaches to handle this effectively.

Implementation Methods

1. Using Promises with Array Methods

async function processArrayWithRemoteConditions() {
    // Example remote function that returns some data
    const getRemoteData = async (id) => {
        const response = await fetch(`/api/data/${id}`);
        return response.json();
    };

    const sourceArray = [1, 2, 3, 4, 5];
    
    // Method 1: Using Promise.all with filter
    const filteredArray = await Promise.all(
        sourceArray.map(async (item) => {
            const remoteResult = await getRemoteData(item);
            return remoteResult.isValid ? item : null;
        })
    ).then(results => results.filter(item => item !== null));

    // Method 2: Using async filter function
    const asyncFilter = async (arr, predicate) => {
        const results = await Promise.all(arr.map(predicate));
        return arr.filter((_v, index) => results[index]);
    };

    const filtered = await asyncFilter(sourceArray, async (item) => {
        const remoteResult = await getRemoteData(item);
        return remoteResult.isValid;
    });
}

2. Using Async Iterators

async function* asyncFilterIterator(array, predicate) {
    for (const item of array) {
        if (await predicate(item)) {
            yield item;
        }
    }
}

async function filterWithIterator() {
    const sourceArray = [1, 2, 3, 4, 5];
    const result = [];

    const remoteCheck = async (item) => {
        const response = await fetch(`/api/validate/${item}`);
        const data = await response.json();
        return data.isValid;
    };

    for await (const item of asyncFilterIterator(sourceArray, remoteCheck)) {
        result.push(item);
    }
    
    return result;
}

3. Using Batch Processing

async function batchProcessArray() {
    const sourceArray = [1, 2, 3, 4, 5];
    const batchSize = 2;
    const results = [];

    // Process array in batches
    for (let i = 0; i < sourceArray.length; i += batchSize) {
        const batch = sourceArray.slice(i, i + batchSize);
        const batchResults = await Promise.all(
            batch.map(async (item) => {
                const response = await fetch(`/api/check/${item}`);
                const data = await response.json();
                return { item, isValid: data.isValid };
            })
        );

        results.push(...batchResults.filter(r => r.isValid).map(r => r.item));
    }

    return results;
}

Error Handling and Best Practices

1. Implementing Retry Logic

async function withRetry(fn, retries = 3) {
    let lastError;
    
    for (let i = 0; i < retries; i++) {
        try {
            return await fn();
        } catch (error) {
            lastError = error;
            await new Promise(resolve => setTimeout(resolve, 1000 * Math.pow(2, i)));
        }
    }
    
    throw lastError;
}

async function processWithRetry() {
    const sourceArray = [1, 2, 3, 4, 5];
    
    const results = await Promise.all(
        sourceArray.map(async (item) => {
            try {
                const result = await withRetry(async () => {
                    const response = await fetch(`/api/data/${item}`);
                    return response.json();
                });
                return result.isValid ? item : null;
            } catch (error) {
                console.error(`Failed to process item ${item}:`, error);
                return null;
            }
        })
    );
    
    return results.filter(item => item !== null);
}

2. Handling Rate Limits

class RateLimiter {
    constructor(maxRequests, timeWindow) {
        this.maxRequests = maxRequests;
        this.timeWindow = timeWindow;
        this.requests = [];
    }

    async acquire() {
        const now = Date.now();
        this.requests = this.requests.filter(time => now - time < this.timeWindow);
        
        if (this.requests.length >= this.maxRequests) {
            const oldestRequest = this.requests[0];
            const waitTime = this.timeWindow - (now - oldestRequest);
            await new Promise(resolve => setTimeout(resolve, waitTime));
        }
        
        this.requests.push(now);
    }
}

async function processWithRateLimit() {
    const rateLimiter = new RateLimiter(5, 1000); // 5 requests per second
    const sourceArray = [1, 2, 3, 4, 5];
    
    const results = [];
    
    for (const item of sourceArray) {
        await rateLimiter.acquire();
        const response = await fetch(`/api/data/${item}`);
        const data = await response.json();
        
        if (data.isValid) {
            results.push(item);
        }
    }
    
    return results;
}

Performance Considerations

  1. Batch Processing: Use batch processing when dealing with large arrays to reduce the number of concurrent requests.
  2. Rate Limiting: Implement rate limiting to avoid overwhelming the remote server.
  3. Caching: Consider caching results when the same conditions are likely to be checked multiple times.
  4. Error Handling: Always implement proper error handling and retry mechanisms.
  5. Memory Management: Be mindful of memory usage when processing large arrays.

Summary

When using remote function results as array conditions:

  • Use Promise.all for parallel execution when possible
  • Implement proper error handling and retries
  • Consider rate limiting for large arrays
  • Use batch processing for better performance
  • Handle edge cases and timeout scenarios
  • Implement proper logging for debugging

Choose the appropriate implementation method based on your specific requirements for performance, reliability, and scalability.

@juna962 thank u for helping others who has questions about APIJSON. however, what he needs is to solve the problem on the server side, not the client/browser side. so unfortunately ur solution is not proper. but we are still appreciate for ur good heart and hope u can contribute more further.

TommyLemon avatar Dec 22 '24 12:12 TommyLemon