Redux Middleware All in One

https://redux.js.org/advanced/middleware

https://redux.js.org/api/applymiddleware

redux-saga

https://redux-saga.js.org/


import {
delay,
put,
select,
call,
takeLatest,
takeEvery,
fork,
getContext,
take,
cancel
} from 'redux-saga/effects';
import { channel } from 'redux-saga';
import escape from 'lodash/escape'; import {
challengeDataSelector,
challengeMetaSelector,
challengeTestsSelector,
initConsole,
updateConsole,
initLogs,
updateLogs,
logsToConsole,
updateTests,
isBuildEnabledSelector,
disableBuildOnError,
types
} from './'; import {
buildChallenge,
canBuildChallenge,
getTestRunner,
challengeHasPreview,
updatePreview,
isJavaScriptChallenge,
isLoopProtected
} from '../utils/build'; // How long before bailing out of a preview.
const previewTimeout = 2500;
let previewTask; export function* executeCancellableChallengeSaga() {
if (previewTask) {
yield cancel(previewTask);
}
const task = yield fork(executeChallengeSaga);
previewTask = yield fork(previewChallengeSaga, { flushLogs: false }); yield take(types.cancelTests);
yield cancel(task);
} export function* executeCancellablePreviewSaga() {
previewTask = yield fork(previewChallengeSaga);
} export function* executeChallengeSaga() {
const isBuildEnabled = yield select(isBuildEnabledSelector);
if (!isBuildEnabled) {
return;
} const consoleProxy = yield channel(); try {
yield put(initLogs());
yield put(initConsole('// running tests'));
// reset tests to initial state
const tests = (yield select(challengeTestsSelector)).map(
({ text, testString }) => ({ text, testString })
);
yield put(updateTests(tests)); yield fork(takeEveryLog, consoleProxy);
const proxyLogger = args => consoleProxy.put(args); const challengeData = yield select(challengeDataSelector);
const challengeMeta = yield select(challengeMetaSelector);
const protect = isLoopProtected(challengeMeta);
const buildData = yield buildChallengeData(challengeData, {
preview: false,
protect
});
const document = yield getContext('document');
const testRunner = yield call(
getTestRunner,
buildData,
{ proxyLogger },
document
);
const testResults = yield executeTests(testRunner, tests); yield put(updateTests(testResults));
yield put(updateConsole('// tests completed'));
yield put(logsToConsole('// console output'));
} catch (e) {
yield put(updateConsole(e));
} finally {
consoleProxy.close();
}
} function* takeEveryLog(channel) {
// TODO: move all stringifying and escaping into the reducer so there is a
// single place responsible for formatting the logs.
yield takeEvery(channel, function*(args) {
yield put(updateLogs(escape(args)));
});
} function* takeEveryConsole(channel) {
// TODO: move all stringifying and escaping into the reducer so there is a
// single place responsible for formatting the console output.
yield takeEvery(channel, function*(args) {
yield put(updateConsole(escape(args)));
});
} function* buildChallengeData(challengeData, options) {
try {
return yield call(buildChallenge, challengeData, options);
} catch (e) {
yield put(disableBuildOnError());
throw e;
}
} function* executeTests(testRunner, tests, testTimeout = 5000) {
const testResults = [];
for (let i = 0; i < tests.length; i++) {
const { text, testString } = tests[i];
const newTest = { text, testString };
// only the last test outputs console.logs to avoid log duplication.
const firstTest = i === 1;
try {
const { pass, err } = yield call(
testRunner,
testString,
testTimeout,
firstTest
);
if (pass) {
newTest.pass = true;
} else {
throw err;
}
} catch (err) {
newTest.message = text;
if (err === 'timeout') {
newTest.err = 'Test timed out';
newTest.message = `${newTest.message} (${newTest.err})`;
} else {
const { message, stack } = err;
newTest.err = message + '\n' + stack;
newTest.stack = stack;
}
yield put(updateConsole(newTest.message));
} finally {
testResults.push(newTest);
}
}
return testResults;
} // updates preview frame and the fcc console.
function* previewChallengeSaga({ flushLogs = true } = {}) {
yield delay(700); const isBuildEnabled = yield select(isBuildEnabledSelector);
if (!isBuildEnabled) {
return;
} const logProxy = yield channel();
const proxyLogger = args => logProxy.put(args); try {
if (flushLogs) {
yield put(initLogs());
yield put(initConsole(''));
}
yield fork(takeEveryConsole, logProxy); const challengeData = yield select(challengeDataSelector); if (canBuildChallenge(challengeData)) {
const challengeMeta = yield select(challengeMetaSelector);
const protect = isLoopProtected(challengeMeta);
const buildData = yield buildChallengeData(challengeData, {
preview: true,
protect
});
// evaluate the user code in the preview frame or in the worker
if (challengeHasPreview(challengeData)) {
const document = yield getContext('document');
yield call(updatePreview, buildData, document, proxyLogger);
} else if (isJavaScriptChallenge(challengeData)) {
const runUserCode = getTestRunner(buildData, { proxyLogger });
// without a testString the testRunner just evaluates the user's code
yield call(runUserCode, null, previewTimeout);
}
}
} catch (err) {
if (err === 'timeout') {
// eslint-disable-next-line no-ex-assign
err = `The code you have written is taking longer than the ${previewTimeout}ms our challenges allow. You may have created an infinite loop or need to write a more efficient algorithm`;
}
console.log(err);
yield put(updateConsole(escape(err)));
}
} export function createExecuteChallengeSaga(types) {
return [
takeLatest(types.executeChallenge, executeCancellableChallengeSaga),
takeLatest(
[
types.updateFile,
types.previewMounted,
types.challengeMounted,
types.resetChallenge
],
executeCancellablePreviewSaga
)
];
}

webpack:///./src/templates/Challenges/redux/execute-challenge-saga.js

refs

https://www.freecodecamp.org/learn/coding-interview-prep/data-structures

https://zzk.cnblogs.com/my/s/blogpost-p?Keywords=redux-saga



xgqfrms 2012-2020

www.cnblogs.com 发布文章使用:只允许注册用户才可以访问!


最新文章

  1. JS里面Data日期格式转换
  2. 初学者-微信小程序 问题解决办法记录
  3. applicationContext配置文件中的属性说明
  4. Windows 提高效率的常用快捷键
  5. join的理解
  6. winform C#获得Mac地址,IP地址,子网掩码,默认网关
  7. location对象及history对象
  8. SharedPreferences实现自动登录记住用户名密码
  9. oracle----复制表中的数据
  10. h.264 去块滤波
  11. Numpy基础笔记
  12. 给即将面临Noip的二班同学
  13. .Net C# Windows Service于server无法启动,错误 193:0xc1
  14. Nginx CONTENT阶段 concat模块
  15. 办公用品管理系统VB——模块
  16. 【Mac】【创建钥匙串】
  17. python判断小数示例&amp;写入文件内容示例
  18. [dpdk][hotplug] DPDK网卡设备热插拔
  19. elasticsearch无故关闭,Log无报错
  20. javascript飞机大战-----006创建敌机

热门文章

  1. https://github.com/golang/go/wiki/CommonMistakes
  2. 我感兴趣的 .NET 开源项目
  3. Trie 前缀树或字典树 确定有限状态自动机
  4. C # 9.0的record
  5. Centos 搭建Hadoop
  6. SLAM01
  7. Microsoft Exchange远程代码执行漏洞(CVE-2020-16875)
  8. Python Package(转)
  9. Git实践笔记(一)
  10. Linux下统计CPU核心数量