json-logic-js icon indicating copy to clipboard operation
json-logic-js copied to clipboard

Async operators

Open jetdream opened this issue 5 years ago • 2 comments

I need to use async operators which make network requests. Any ideas how to implement it?

jetdream avatar Jun 23 '20 22:06 jetdream

yes, async operators would be quite interesting.

having an object with an async getter does not really help, because when accessing async getters you must add await, and the entire logic in jsonlogic.apply is sync..

const user = {
    name: "John",
    surname: "Doe",
    get isRegistered() {
        return new Promise((resolve, reject) =>
         // Imagine you are doing your network request here and wait for results
            setTimeout(() => {
                console.log("got async results ")
                resolve(true), 2000
            })
        )
    }
}

console.log(user.isRegistered) // Promise(pending)
console.log(await user.isRegistered) // true ( but after 2 seconds)

const checkCondition = async () => {
    const rules = {
        '==': [{"var": "isSubscribed"}, true]
    }
    return jsonLogic.apply(rules, user)
}

Something like this does not work because jsonlogic apply is sync, and if we could make it async it should then check if the prop being accessed is an async getter and in such case access it using await..

any ideas?

dvddpl avatar Oct 15 '20 13:10 dvddpl

I apologize for shilling, but I want to post this here in case anyone is looking for this kind of functionality 😅

In order to support this functionality, I ended up doing a full rewrite of the json-logic mechanisms & published an alternative module:

https://totaltechgeek.github.io/json-logic-engine/docs/async

import { AsyncLogicEngine } from 'json-logic-engine'

const engine = new AsyncLogicEngine()

engine.addMethod('after250ms', async (n) => {
    return new Promise(resolve => {
        setTimeout(() => {
            resolve(n)
        }, 250)
    })
})

async function main () {
    const f = await engine.build({ '+': [{ after250ms: 1 }, 1] })
    console.log(await f()) // prints 2
}

The module offers both a synchronous & asynchronous engine, and with its compilation mechanism it can attempt to optimize performance by chaining synchronous operations to avoid the overhead of the event loop.

TotalTechGeek avatar Apr 28 '21 18:04 TotalTechGeek