【发布时间】:2018-08-18 04:59:30
【问题描述】:
我正在构建一个类似待办事项列表的功能,当在输入任务字段上按下 Enter 时添加一个任务。 Enter 调用一个 API(添加任务),执行大约需要 200 毫秒。由于这是阻塞调用,它会阻碍我的代码完全执行并影响我的系统的可用性。这是我想要实现的代码示例。
handleChange(事件){
if (e.key === 'Enter') {
targetTaskId = e.target.getAttribute("data-downlink")
this.props.addTask(this.props.currentProject.id, '', '', taskId, this.props.currentTasks) //this function calls an add Task API which halts my system momentarily
targetSelector = targetTaskId
$('#' + targetSelector).focus()
this.setState({activeTask: targetSelector})
highlightActiveComponent(targetTaskId)
}
}
//添加任务
export function addTask (project_id, taskName, taskNotes, upLink, taskList) {
console.log('Add Task API call', project_id, taskName, taskNotes, upLink)
return (dispatch) => {
callApi('tasks?projectId=' + project_id + '&name=' + taskName + '¬es=' + taskNotes + '&upLink=' + upLink, 'post')
.then(res => {
console.log('Response new task ', res)
let newTask = {name: res.name, id: res.id, notes: res.notes, upLink: upLink, projectId: project_id, assignee: 0, completed: 0, tags: [], isLiked: false, stories: [], likes: [], downLink: res.downLink}
let newTaskList = addTaskToTaskList(taskList, upLink, newTask)
dispatch(updateTasks({currentTasks: newTaskList}))
dispatch({ type: 'SET_ACTIVE_TASK_ID', payload: res.id })
})
}
}
//获取
export const API_URL = 'https://clients.rohan.axcelmedia.ca/v1'
export default function callApi (endpoint, method = 'get', body) {
let headers = {
'Accept': 'application/json',
'Content-Type' : 'application/json'
}
if (auth.loggedIn()) {
headers = _.merge(headers, {
Authorization: `Bearer ${auth.getToken()}`
})
}
return fetch(`${API_URL}/${endpoint}`, {
headers,
method,
body: JSON.stringify(body)
}).then(response => {
return response
}).then(response => response.json().then(json => ({ json, response })))
.then(({ json, response }) => {
if (!response.ok) {
return Promise.reject(json)
}
return json
})
.then(
response => response,
error => error
)
}
将任务添加到任务列表
export function addTaskToTaskList(tasks, upLink, newTask){
updateTaskDownLink(tasks, newTask.upLink, newTask.id)
updateTaskUpLink(tasks, newTask.downLink, newTask.id)
if(upLink == 0){
tasks.unshift(newTask)
// console.log("Added in the start", tasks)
return JSON.parse(JSON.stringify(tasks))
}
let myIndex = getIndexOfTaskById(tasks, upLink)
console.log("Added the new task from helper", myIndex)
if (myIndex) {
console.log("Added the new task")
tasks.splice(myIndex + 1, 0, newTask);
// console.log("New Task List", JSON.parse(JSON.stringify(tasks)))
}
return JSON.parse(JSON.stringify(tasks))
}
export function updateTaskUpLink(tasks, taskId, upLink){
tasks.forEach(function(element, index) {
if(element.id == taskId) { element.upLink = upLink }
});
return tasks
}
export function updateTaskDownLink(tasks, taskId, downLink){
tasks.forEach(function(element, index) {
if(element.id == taskId) { element.downLink = downLink }
});
return tasks
}
我的问题是,无论如何以非阻塞方式调用此 API,以便我的代码继续执行,当收到来自 api 的响应时,我的光标以无缝方式移动到新任务。 任何帮助,将不胜感激。谢谢 [编辑]:添加了 fetch 函数来演示异步调用
【问题讨论】:
-
使
addTask使其 HTTP 请求异步并最有可能使用承诺/回调。 -
javascript 在设计上是异步且非阻塞的,也许您的代码中的其他地方发生了某些事情导致您的应用程序呈现不利?也许在
addTask或highlightActiveComponent中发生了昂贵的计算 -
@james 是的,昂贵的计算发生在 add 任务中,它调用需要一些时间来处理的 api。我正在使用同构提取,人们建议我改用 axios
-
@RafayShahid 使用 fetch 或 axios 或 xhrhttp 或其他什么都没关系,默认情况下,JS 中的所有 api 调用都是异步的。 js中的同步操作只有一手,而且大部分都是和文件系统操作有关的。
-
@James 好的,所以没有办法让这个调用在 js 中非阻塞?
标签: javascript reactjs nonblocking