2015-11-09 61 views
1

因此,我瞭解到回調函數是一個作爲參數傳遞給另一個函數的函數,並且在其他函數內部調用(或執行)了回調函數。下面是一個例子。 「回調」被放置在第三個參數處,函數將「result」的值傳遞給「callback」,然後「callback」以函數的形式被調用。嘗試瞭解ToDoList項目中的回調函數

var merge = function(array1, array2, callback){ 
    var result = []; 
    for (var i = 0; i < array1.length; i++) { 
    result[i] = array1[i] + array2[i]; 
    }; 
callback(result) 
}; 

var x=merge([1, 2, 3, 4], [5, 6, 7, 8], function(merged) {console.log(merged)}); 

然而,當我試圖在實際項目中使用回調,下方的等TodoList的。我知道使用回調函數(我瞭解到回調用於事件處理程序???),但爲什麼這些回調的格式與我上面學習的例子有很大不同?例如,正如你所看到的,我使用** **突出顯示了那些我認爲使用了回調的部分...例如,在addTask函數中,「bindTaskEvents」對我來說看起來像是一個回調,但爲什麼它不傳遞給addTask函數作爲參數?另外,我沒有看到「bindTaskEvents」稍後調用的地方以及以何種格式?

var addTask=function(){ 
var listItem=createNewTaskElement(taskInput.value) 
incompleteTasksHolder.appendChild(listItem); 
    **bindTaskEvents(listItem,taskCompleted);** 
    taskInput.value=""; 

}; 

附:我知道這個項目並不是純粹基於JS,而是基於文檔對象模型構建的,它似乎讓像我這樣的初學者試圖學習JS的JS概念複雜化。
---------------下面是完整的項目,供您參考--------------------

var taskInput=document.getElementById("new-task"); 
var addButton=document.getElementsByTagName("button")[0]; //first button 
var incompleteTasksHolder=document.getElementById("incomplete-tasks"); 
var completedTasksHolder=document.getElementById("completed-tasks"); 


var createNewTaskElement=function(taskString){ //checkbox 
    var listItem=document.createElement("li") 
    var checkBox=document.createElement("input") 
    var label=document.createElement("label") 
    var editInput=document.createElement("input") 
    var editButton=document.createElement("button") 
    var deleteButton=document.createElement("button") 

    checkBox.type="checkbox"; 
    editInput.type="text"; 

    editButton.innerText="Edit"; 
    editButton.className="edit"; 
    deleteButton.innerText="Delete"; 
    deleteButton.className="delete"; 

    label.innerText = taskString; 

    listItem.appendChild(checkBox); 
    listItem.appendChild(label); 
    listItem.appendChild(editInput); 
    listItem.appendChild(editButton); 
    listItem.appendChild(deleteButton); 

return listItem; 
} 

var addTask=function(){ 
console.log("Add task..."); 
var listItem=createNewTaskElement(taskInput.value) 
incompleteTasksHolder.appendChild(listItem); 
    **bindTaskEvents(listItem,taskCompleted);** 
    taskInput.value=""; 

}; 

var editTask=function(){ 
console.log("edit task..."); 

var listItem=this.parentNode; 

var editInput=listItem.querySelector("input[type=text]"); 
var label=listItem.querySelector("label"); 
var containsClass=listItem.classList.contains("editMode"); 

    if(containsClass){ 
    label.innerText=editInput.value; 
    }else{ 
    editInput.value=label.innerText; 
    } 
    listItem.classList.toggle("editMode"); 

    }; 

var deleteTask=function(){ 
console.log("delete task..."); 


    var listItem=this.parentNode; 
    var ul=listItem.parentNode; 
    ul.removeChild(listItem); 
} 

var taskCompleted=function(){ 
console.log("Completed task..."); 
var listItem= this.parentNode 
completedTasksHolder.appendChild(listItem); 
    **bindTaskEvents(listItem, taskIncomplete);** 
} 

var taskIncomplete=function(){ 
console.log("Incompleted task..."); 
    var listItem= this.parentNode; 
incompleteTasksHolder.appendChild(listItem); 
    **bindTaskEvents(listItem, taskCompleted);** 

} 

var bindTaskEvents=function(taskListItem,checkBoxEventHandler){   
console.log("Bind list item events"); 
    var checkBox = taskListItem.querySelector('input[type=checkbox]'); 
    var editButton = taskListItem.querySelector('button.edit'); 
    var deleteButton = taskListItem.querySelector('button.delete'); 
    editButton.onclick = editTask; 
    deleteButton.onclick = deleteTask; 
    checkBox.onchange = checkBoxEventHandler; 
}; 


var ajaxRequest=function(){ 
console.log("AJAX request"); 
} 

addButton.addEventListener("click",addTask);; 
addButton.addEventListener("click",ajaxRequest); 

for(var i=0;i<incompleteTasksHolder.children.length;i++){ 
**bindTaskEvents(incompleteTasksHolder.children[i], taskCompleted);** 

} 

for(var i=0;i<completedTasksHolder.children.length;i++){ 
**bindTaskEvents(completedTasksHolder.children[i], taskIncomplete);** 

} 
+3

'bindTaskEvents'只是另一個函數;它不是回調*,因爲它不作爲參數傳遞給函數。任何函數都可以用作回調函數,但並不是所有函數調用都是調用回調函數。 – Pointy

+0

那麼這個項目有沒有回電?我瞭解到回調用於事件處理程序 – Danny

回答

2

沒有「回調」的位置:

var addTask=function(){ 
    var listItem=createNewTaskElement(taskInput.value) 
    incompleteTasksHolder.appendChild(listItem); 
    bindTaskEvents(listItem,taskCompleted); // <-- this is not a callback 
    taskInput.value=""; 
}; 

所有這一切發生在這裏是一個函數(addTask)被調用另一個函數(bindTaskEvents)。沒有什麼特別的,只是調用一個像你在其他地方一樣的功能。

爲了它是一個回調,那就要被提供給函數作爲參數:

var addTask=function(someCallback){ 
    var listItem=createNewTaskElement(taskInput.value) 
    incompleteTasksHolder.appendChild(listItem); 
    someCallback(listItem,taskCompleted); // <-- this IS a callback 
    taskInput.value=""; 
}; 

但在這裏,這是情況並非如此。


在結構上,最接近事「回調」我在這段代碼中看到的是在這裏:

var bindTaskEvents=function(taskListItem,checkBoxEventHandler){   
    console.log("Bind list item events"); 
    var checkBox = taskListItem.querySelector('input[type=checkbox]'); 
    var editButton = taskListItem.querySelector('button.edit'); 
    var deleteButton = taskListItem.querySelector('button.delete'); 
    editButton.onclick = editTask; 
    deleteButton.onclick = deleteTask; 
    checkBox.onchange = checkBoxEventHandler; // <-- here 
}; 

這不是一個「回調」本身,而是它在概念類似 。在這種情況下,bindTaskEvents正在期待函數作爲參數。但不是調用該函數(作爲一個回調),它使用該函數作爲它創建的元素的事件處理程序。因此,該函數將在頁面生命週期的某個時間點被調用,以便處理該事件,但不是直接由函數調用。