我有一个提供标准扩展点的JavaScript小部件。其中之一是beforereate函数。它应该返回false以防止创建一个项。
我已经使用jQuery在这个函数中添加了一个Ajax调用:
beforecreate: function (node, targetNode, type, to) {
jQuery.get('http://example.com/catalog/create/' + targetNode.id + '?name=' + encode(to.inp[0].value),
function (result) {
if (result.isOk == false)
alert(result.message);
});
}
但是我想阻止小部件创建项目,所以我应该在母函数中返回false,而不是在回调中返回false。是否有一种方法可以使用jQuery或任何其他浏览器内API执行同步AJAX请求?
来自jQuery文档:您将异步选项指定为false以获得同步Ajax请求。然后你的回调函数可以在你的母函数继续之前设置一些数据。
下面是你的代码如果按照建议修改后的样子:
beforecreate: function (node, targetNode, type, to) {
jQuery.ajax({
url: 'http://example.com/catalog/create/' + targetNode.id + '?name=' + encode(to.inp[0].value),
success: function (result) {
if (result.isOk == false) alert(result.message);
},
async: false
});
}
async: false会导致浏览器被阻塞。
对于非阻塞同步解决方案,您可以使用以下方法:
ES6/ECMAScript2015
在ES6中,你可以使用生成器和co库:
beforecreate: function (node, targetNode, type, to) {
co(function*(){
let result = yield jQuery.get('http://example.com/catalog/create/' + targetNode.id + '?name=' + encode(to.inp[0].value));
//Just use the result here
});
}
ES7
在ES7中,你可以使用async await:
beforecreate: function (node, targetNode, type, to) {
(async function(){
let result = await jQuery.get('http://example.com/catalog/create/' + targetNode.id + '?name=' + encode(to.inp[0].value));
//Just use the result here
})();
}
所有这些答案都忽略了一点,即使用async:false执行Ajax调用将导致浏览器挂起,直到Ajax请求完成。使用流控制库可以解决这个问题,而不需要挂起浏览器。下面是一个Frame.js的例子:
beforecreate: function(node,targetNode,type,to) {
Frame(function(next)){
jQuery.get('http://example.com/catalog/create/', next);
});
Frame(function(next, response)){
alert(response);
next();
});
Frame.init();
}
这是我的简单实现ASYNC请求与jQuery。我希望这能对大家有所帮助。
var queueUrlsForRemove = [
'http://dev-myurl.com/image/1',
'http://dev-myurl.com/image/2',
'http://dev-myurl.com/image/3',
];
var queueImagesDelete = function(){
deleteImage( queueUrlsForRemove.splice(0,1), function(){
if (queueUrlsForRemove.length > 0) {
queueImagesDelete();
}
});
}
var deleteImage = function(url, callback) {
$.ajax({
url: url,
method: 'DELETE'
}).done(function(response){
typeof(callback) == 'function' ? callback(response) : null;
});
}
queueImagesDelete();