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. Generateblocks
(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 then2s
and then callhttp://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