Js sends a request and returns the result after determining that the request has a value.

when I send an ajax request background result, the background returns data at a different time

.

because blockchain technology is used, when the foreground requests a smart contract ( method ), the steps performed in the background are:

1. Execution method (execute smart contract)
2. Generate blocks (process time is not equal to 100ms-2000ms)
3. Return the result to the receptionist

the process of sending a request at the front end:

  • 1. Send a request (smart contract)
    example: http://127.0.0.1/contract
  • 2. Send another request (check whether the backend returns a result)
    example: http://127.0.0.1/status

    if the data has not been written to the block in the background, the result returned is

    blockid: 
    result:

    if the backend has already written the data to the block, the result returned is

    blockid: 1
    result: {name: "xxxx", age: "20"}
  • 3. Wait for the data to be returned by the backend (because the time of the data returned by the backend is 100ms-2000ms), so we all call the smart contract (method) http://127.0.0.1/contract and then 2s and then call http://127.0.0.1/status.

problems encountered today:

  • the front end needs to wait for each call to a contract (method) ( 2s ), resulting in a very bad user experience

what we can think of now is whether we can call the contract http://127.0.0.1/status (method) in a loop and then make a judgment in it, and return the data when blockid and result are not equal to null .

tell me how to use jquery and native javascript to do this loop or Promise to solve this problem.

I"ll post a piece of code below. An example I found on the Internet uses the Observable module in the rxjs package of react .

const txExecEpic: Epic = (action$, store, { api }) => action$.ofAction(txExec.started)
    .flatMap(action => {
        const state = store.getState();
        const client = api(state.auth.session);
        const publicKey = keyring.generatePublicKey(action.payload.privateKey, true);

        // 
        if (!keyring.validatePrivateKey(action.payload.privateKey)) {
            return Observable.of(txExec.failed({
                params: action.payload,
                error: {
                    type: "E_INVALID_PASSWORD",
                    error: null
                }
            }));
        }

        return Observable.fromPromise(client.txCall({
            requestID: action.payload.requestID,
            pubkey: publicKey,
            signature: action.payload.signature,
            time: action.payload.time

        })).flatMap(result => Observable.defer(() => client.txStatus({
            hash: result.hash

        }).then(status => {
            if (!status.blockid && !status.errmsg) {
                throw "E_PENDING";
            }
            else {
                console.log(status);
                return status;
            }

        })).retryWhen(errors =>
            errors.delay(100)

        ).flatMap(txResult => {
            if (txResult.blockid) {
                const actions = Observable.of<Action>(
                    txExec.done({
                        params: action.payload,
                        result: {
                            block: txResult.blockid,
                            result: txResult.result
                        }
                    }),
                    authorize(action.payload.privateKey)
                );

                if (action.payload.tx.silent) {
                    return actions;
                }
                else {
                    return actions.concat(Observable.of(enqueueNotification({
                        id: uuid.v4(),
                        type: "TX_SUCCESS",
                        params: {
                            block: txResult.blockid,
                            tx: action.payload.tx
                        }
                    })));
                }
            }
            else {
                return Observable.of(txExec.failed({
                    params: action.payload,
                    error: {
                        type: txResult.errmsg.type as TTxError,
                        error: txResult.errmsg.error
                    }
                }));
            }

        })).catch(error => Observable.of(txExec.failed({
            params: action.payload,
            error: {
                type: (error.errmsg ? error.errmsg.type : error.error) as TTxError,
                error: error.errmsg ? error.errmsg.error : error.msg
            }
        })));
    });

Please answer as many solutions as possible and post the sample code

Mar.13,2021

I think you can consider the websocket approach. After all, ajax is still a request and a response. However, the websocket backend should also be supported accordingly. You can discuss in detail


you can learn about websocket and polling to see which is more suitable for your project needs


you can consider using websocket, to actively push messages to the foreground page

.
Menu