mirror of
https://github.com/lowdefy/lowdefy.git
synced 2025-02-23 14:39:32 +08:00
feat(engine): Add async option to actions
This commit is contained in:
parent
d5d19b1872
commit
81036db446
@ -27,18 +27,46 @@ class Actions {
|
||||
this.actions = actions;
|
||||
}
|
||||
|
||||
async callAsyncAction({ action, arrayIndices, block, event, index, responses }) {
|
||||
try {
|
||||
const response = await this.callAction({
|
||||
action,
|
||||
arrayIndices,
|
||||
block,
|
||||
event,
|
||||
index,
|
||||
responses,
|
||||
});
|
||||
responses[action.id] = response;
|
||||
} catch (error) {
|
||||
responses[action.id] = error;
|
||||
console.error(error);
|
||||
}
|
||||
}
|
||||
|
||||
async callActionLoop({ actions, arrayIndices, block, event, responses }) {
|
||||
for (const [index, action] of actions.entries()) {
|
||||
try {
|
||||
const response = await this.callAction({
|
||||
action,
|
||||
arrayIndices,
|
||||
block,
|
||||
event,
|
||||
index,
|
||||
responses,
|
||||
});
|
||||
responses[action.id] = response;
|
||||
if (action.async === true) {
|
||||
this.callAsyncAction({
|
||||
action,
|
||||
arrayIndices,
|
||||
block,
|
||||
event,
|
||||
index,
|
||||
responses,
|
||||
});
|
||||
} else {
|
||||
const response = await this.callAction({
|
||||
action,
|
||||
arrayIndices,
|
||||
block,
|
||||
event,
|
||||
index,
|
||||
responses,
|
||||
});
|
||||
responses[action.id] = response;
|
||||
}
|
||||
} catch (error) {
|
||||
responses[action.id] = error;
|
||||
throw {
|
||||
|
@ -21,15 +21,26 @@ import actions from '../../src/actions/index.js';
|
||||
|
||||
jest.mock('../../src/actions/index.js', () => ({
|
||||
ActionSync: jest.fn(({ params }) => params),
|
||||
ActionAsync: jest.fn(({ params }) => Promise.resolve(params)),
|
||||
ActionAsync: jest.fn(async ({ params }) => {
|
||||
await timeout(params.ms || 1);
|
||||
return params;
|
||||
}),
|
||||
ActionError: jest.fn(() => {
|
||||
throw new Error('Test error');
|
||||
}),
|
||||
CatchActionError: jest.fn(() => {
|
||||
throw new Error('Test catch error');
|
||||
}),
|
||||
ActionAsyncError: jest.fn(async ({ params }) => {
|
||||
await timeout(params.ms || 1);
|
||||
throw new Error('Test error');
|
||||
}),
|
||||
}));
|
||||
|
||||
const timeout = (ms) => {
|
||||
return new Promise((resolve) => setTimeout(resolve, ms));
|
||||
};
|
||||
|
||||
const pageId = 'one';
|
||||
|
||||
const RealDate = Date;
|
||||
@ -46,8 +57,8 @@ const arrayIndices = [];
|
||||
const eventName = 'eventName';
|
||||
|
||||
// Comment out to use console.log
|
||||
console.log = () => {};
|
||||
console.error = () => {};
|
||||
// console.log = () => {};
|
||||
// console.error = () => {};
|
||||
|
||||
beforeEach(() => {
|
||||
global.Date = mockDate;
|
||||
@ -181,6 +192,51 @@ test('call 2 actions', async () => {
|
||||
});
|
||||
});
|
||||
|
||||
test('call async then sync action', async () => {
|
||||
const rootBlock = {
|
||||
blockId: 'root',
|
||||
meta: {
|
||||
category: 'context',
|
||||
},
|
||||
};
|
||||
const context = await testContext({
|
||||
lowdefy,
|
||||
rootBlock,
|
||||
});
|
||||
const Actions = context.Actions;
|
||||
const res = await Actions.callActions({
|
||||
actions: [
|
||||
{ id: 'test1', type: 'ActionAsync', params: 'params1' },
|
||||
{ id: 'test2', type: 'ActionSync', params: 'params2' },
|
||||
],
|
||||
arrayIndices,
|
||||
block: { blockId: 'blockId' },
|
||||
catchActions: [],
|
||||
event: {},
|
||||
eventName,
|
||||
});
|
||||
expect(res).toEqual({
|
||||
blockId: 'blockId',
|
||||
event: {},
|
||||
eventName: 'eventName',
|
||||
responses: {
|
||||
test1: {
|
||||
type: 'ActionSync',
|
||||
index: 1,
|
||||
response: 'params2',
|
||||
},
|
||||
test2: {
|
||||
type: 'ActionAsync',
|
||||
index: 0,
|
||||
response: 'params1',
|
||||
},
|
||||
},
|
||||
success: true,
|
||||
startTimestamp: { date: 0 },
|
||||
endTimestamp: { date: 0 },
|
||||
});
|
||||
});
|
||||
|
||||
test('operators are evaluated in params, skip and messages', async () => {
|
||||
const rootBlock = {
|
||||
blockId: 'root',
|
||||
@ -1097,3 +1153,125 @@ test('Call catchActions when actions throws error and catchActions throws error'
|
||||
});
|
||||
expect(actions.ActionAsync.mock.calls.length).toBe(1);
|
||||
});
|
||||
|
||||
test('call 2 actions, first with async: true', async () => {
|
||||
const rootBlock = {
|
||||
blockId: 'root',
|
||||
meta: {
|
||||
category: 'context',
|
||||
},
|
||||
};
|
||||
const context = await testContext({
|
||||
lowdefy,
|
||||
rootBlock,
|
||||
});
|
||||
const Actions = context.Actions;
|
||||
const res = await Actions.callActions({
|
||||
actions: [
|
||||
{ id: 'test1', type: 'ActionAsync', async: true, params: { ms: 100 } },
|
||||
{ id: 'test2', type: 'ActionSync', params: 'params2' },
|
||||
],
|
||||
arrayIndices,
|
||||
block: { blockId: 'blockId' },
|
||||
catchActions: [],
|
||||
event: {},
|
||||
eventName,
|
||||
});
|
||||
expect(res).toEqual({
|
||||
blockId: 'blockId',
|
||||
event: {},
|
||||
eventName: 'eventName',
|
||||
responses: {
|
||||
test2: {
|
||||
type: 'ActionSync',
|
||||
index: 1,
|
||||
response: 'params2',
|
||||
},
|
||||
},
|
||||
success: true,
|
||||
startTimestamp: { date: 0 },
|
||||
endTimestamp: { date: 0 },
|
||||
});
|
||||
await timeout(110);
|
||||
expect(res).toEqual({
|
||||
blockId: 'blockId',
|
||||
event: {},
|
||||
eventName: 'eventName',
|
||||
responses: {
|
||||
test1: {
|
||||
type: 'ActionAsync',
|
||||
index: 0,
|
||||
response: { ms: 100 },
|
||||
},
|
||||
test2: {
|
||||
type: 'ActionSync',
|
||||
index: 1,
|
||||
response: 'params2',
|
||||
},
|
||||
},
|
||||
success: true,
|
||||
startTimestamp: { date: 0 },
|
||||
endTimestamp: { date: 0 },
|
||||
});
|
||||
});
|
||||
|
||||
test('call async: true with error', async () => {
|
||||
const rootBlock = {
|
||||
blockId: 'root',
|
||||
meta: {
|
||||
category: 'context',
|
||||
},
|
||||
};
|
||||
const context = await testContext({
|
||||
lowdefy,
|
||||
rootBlock,
|
||||
});
|
||||
const Actions = context.Actions;
|
||||
const res = await Actions.callActions({
|
||||
actions: [
|
||||
{ id: 'test1', type: 'ActionAsyncError', async: true, params: { ms: 100 } },
|
||||
{ id: 'test2', type: 'ActionSync', params: 'params2' },
|
||||
],
|
||||
arrayIndices,
|
||||
block: { blockId: 'blockId' },
|
||||
catchActions: [],
|
||||
event: {},
|
||||
eventName,
|
||||
});
|
||||
expect(res).toEqual({
|
||||
blockId: 'blockId',
|
||||
event: {},
|
||||
eventName: 'eventName',
|
||||
responses: {
|
||||
test2: {
|
||||
type: 'ActionSync',
|
||||
response: 'params2',
|
||||
index: 1,
|
||||
},
|
||||
},
|
||||
endTimestamp: { date: 0 },
|
||||
startTimestamp: { date: 0 },
|
||||
success: true,
|
||||
});
|
||||
await timeout(110);
|
||||
expect(res).toEqual({
|
||||
blockId: 'blockId',
|
||||
event: {},
|
||||
eventName: 'eventName',
|
||||
responses: {
|
||||
test2: {
|
||||
type: 'ActionSync',
|
||||
response: 'params2',
|
||||
index: 1,
|
||||
},
|
||||
test1: {
|
||||
type: 'ActionAsyncError',
|
||||
error: new Error('Test error'),
|
||||
index: 0,
|
||||
},
|
||||
},
|
||||
success: true,
|
||||
startTimestamp: { date: 0 },
|
||||
endTimestamp: { date: 0 },
|
||||
});
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user