// Nope
if (!data.name) {
tip('請輸入您的姓名')
} else if (!data.identify) {
tip('請輸入您的身份證')
} else if (!data.cardId) {
tip('請輸入您的借記卡號')
} else if (!data.bankSelect) {
tip('請選擇借記卡所屬銀行')
} else if (!data.cardTel) {
tip('請輸入您的預留手機號碼')
} else {
submitAuthentication()
}
複製代碼
// Yep
import Schema from 'async-validator'
new Schema({
name: { type: 'string', required: true, message: '請輸入您的姓名' },
identify: { type: 'string', required: true, message: '請輸入您的身份證' },
cardId: { type: 'string', required: true, message: '請輸入您的借記卡號' },
bankSelect: { type: 'object', required: true, message: '請選擇借記卡所屬銀行' },
cardTel: { type: 'string', required: true, message: '請輸入您的預留手機號碼' }
}).validate(dataToCheck).then(() => {
that.submitAuthentication()
}).catch(({ errors, fields }) => {
// errors是全部錯誤的數組,
// fields是全部驗證錯誤的字段爲key,相應的錯誤爲value
console.log(errors)
// 僅提示第一個錯誤信息,
// 這裏建議把錯誤信息及時反饋到表單上的每一個字段上
tip(errors[0].message)
})
// 異步判斷
{
name: { type: 'string', required: true, message: '請輸入您的姓名' },
identify: [
{ type: 'string', required: true, message: '請輸入您的身份證' },
{ asyncValidator(rule, value, callback, source, options) {
api.check(someData).then((data) => {
data.valid ? callback() : callback(new Error(data.message))
}).catch(error => {
callback(new Error(error))
})
}}
],
cardId: { type: 'string', required: true, message: '請輸入您的借記卡號' },
bankSelect: { type: 'object', required: true, message: '請選擇借記卡所屬銀行' },
cardTel: { type: 'string', required: true, message: '請輸入您的預留手機號碼' }
}
複製代碼
async-validator: github.com/yiminghe/as…html
本質上第一種方式也屬於策略模式git
參考:juejin.im/post/5bdfef…github
// Nope
const aCase = 'case1'
if(aCase === 'case1') {
// do sth
}
if(aCase === 'case2') {
// do sth
}
if(aCase === 'case3') {
// do sth
}
if(aCase === 'case4') {
// do sth
}
複製代碼
// Better, but Nope
switch (status){
case 1:
sendLog('processing')
jumpTo('IndexPage')
break
case 2:
case 3:
sendLog('fail')
jumpTo('FailPage')
break
case 4:
sendLog('success')
jumpTo('SuccessPage')
break
case 5:
sendLog('cancel')
jumpTo('CancelPage')
break
default:
sendLog('other')
jumpTo('Index')
break
}
複製代碼
// Much better, Yep
const aCase = 'case1'
// 基本類型做爲key
new Map([
['case1',()=>{/*do sth*/}],
['case2',()=>{/*do sth*/}],
//...
]).get(aCase)()
// object做爲key
const actions = new Map([
[{identity:'guest',status:1},()=>{/* functionA */}],
[{identity:'guest',status:2},()=>{/* functionA */}],
[{identity:'guest',status:3},()=>{/* functionA */}],
[{identity:'guest',status:4},()=>{/* functionA */}],
[{identity:'guest',status:5},()=>{/* functionB */}],
//...
])
// 正則用法
const actions = ()=>{
const functionA = ()=>{/*do sth*/}
const functionB = ()=>{/*do sth*/}
const functionC = ()=>{/*send log*/}
return new Map([
[/^guest_[1-4]$/,functionA],
[/^guest_5$/,functionB],
[/^guest_.*$/,functionC],
//...
])
}
const onButtonClick = (identity,status)=>{
// 過濾某些策略
let action = [...actions()].filter(([key,value])=>(key.test(`${identity}_${status}`)))
action.forEach(([key,value])=>value.call(this))
}
複製代碼
Map的key能夠是任意類型的數據編程
// Nope
// 溫度爲0時輸出水結冰了
if(temp === 0) {
return 'water freezes at 0°C'
// 溫度爲100時輸出
} else if(temp === 100) {
return 'water boils at 100°C'
} else {
return 'nothing special happens at ' + temp + '°C'
}
複製代碼
使用函數式編程庫Ramda:api
// Yep
const fn = R.cond([
[R.equals(0), R.always('water freezes at 0°C')],
[R.equals(100), R.always('water boils at 100°C')],
[R.T, temp => 'nothing special happens at ' + temp + '°C']
]);
fn(0); //=> 'water freezes at 0°C'
fn(50); //=> 'nothing special happens at 50°C'
fn(100); //=> 'water boils at 100°C'
複製代碼
Ramda: ramda.cn/docs/#cond數組
函數式編程的本質是Pointfree的概念,細讀這篇文章便能明白爲何函數式編程會出現app
Pointfree: www.ruanyifeng.com/blog/2017/0…異步