2014-04-24 33 views
1

我想以與mocha相同的方式實現可選的異步回調。如何像可選的異步回調一樣實現摩卡?

我的意思是,我想有哪些既可以是同步和異步回調函數。

當用戶使用「完成」這是異步,當沒有回調參數比它的同步可選的回調參數。

 
// Sync version 
it('does something sync', function() { 
    console.log('this is sync version') 
}); 

// Async version 
it('does something async, function(done) { 
    setTimeout(function() { 
    done(true); 
    }, 1000); 
}); 

如何運作「它」區分,如果回調是同步還是異步?

任何想法如何實現這一點?

回答

3

如果你可以假設你的函數的toString沒有被覆蓋,你可以使用它在用戶定義的函數來檢查它是否有一個名爲done參數,例如:

function argIndexOf(f, arg) { 
    var s = f + ''; 
    return s.substring(s.indexOf('(') + 1, s.indexOf(')')) 
    .replace(/\s+/g, '').split(',').indexOf(arg); 
} 

argIndexOf(function(){}, 'done'); // -1 
argIndexOf(function(done){}, 'done') // 0 
argIndexOf(function(arg1, done){}, 'done') // 1 

該函數將採取在一個函數作爲參數和返回值的位置是done說法,或者-1如果是沒有的。它使用Array.prototype.indexOf,如果您想在IE 8或更早版本中使用它,則需要使用shimmed。你已經標記了問題node.js,所以我會認爲這不是問題。

你甚至可以將它添加到Function.prototype的,但如果你希望你的代碼與其他人打得好,這是非常氣餒:

Function.prototype.indexOf = Function.prototype.indexOf || function(arg) { 
    var s = this + ''; 
    return s.substring(s.indexOf('(') + 1, s.indexOf(')')) 
    .replace(/\s+/g, '').split(',').indexOf(arg); 
}; 

然後,你可以只使用:

func.indexOf('done') 

您也可以使用apply,它會忽略負指數,因此調用回調並傳入「已完成」的值:

var args = []; 
args[func.indexOf('done')] = done_callback; 
func.apply(func, args); 
+0

真是巧妙的把戲。可能我會堅持這一點。感謝分享! – korCZis

+0

@korCZis謝謝,沒有問題:) @ MSCDEX的答案是正確的,雖然,摩卡不會測試你的論點實際上是名爲'done',它只是檢查是否有至少'1'的說法,它不如果'Function.prototype.toString'已被覆蓋,則中斷。 – Paulpro

7

摩卡僅在測試功能的回調參數是否存在等checksfunction.length用於確定回調有多少個參數。

+0

+1,再往下看179就是摩卡如何處理'done()'。 https://github.com/visionmedia/mocha/blob/master/lib/runnable.js#L179 –

+0

我明白了......謝謝你指點我。 – korCZis

+0

太棒了,我不知道'function.length'被映射到參數count。很乾淨! –