我的网站连接本地服务,该服务使用PIN Pad管理CardReader。使用此设备可以完成许多不同的操作。以下是其中一个例子:
之前我曾经在彼此之间链接回调,但现在,因为有新的操作,也使用像“lock”和“release”这样的方法,我需要更改我的代码,以便第1步的代码3是可重复使用的。
我一直试图用jQuery承诺来解决这个问题,但我对此很新,而且我还没有真正弄清楚它们是如何工作的。有人可以帮我一把吗?
这是我现在使用的代码示例。我已从函数内部删除了业务逻辑,以简化示例:
var CardReader = {
////////////////////
// Different possible messages to the Card Reader
////////////////////
lockDevice: function() {
this.makeAjaxCall("GET", "/LockDevice", this.lockDeviceCallback);
},
getPin: function() {
this.makeAjaxCall("POST", "/getPin", this.getPinCallback);
},
releaseDevice: function() {
this.makeAjaxCall("POST", "/Release", this.releaseDeviceCallback);
},
//////////////////
// Callbacks for each message to the Card Reader
//////////////////
lockDeviceCallback: function(jqXHR, textStatus) {
if (textStatus !== "success") { return; }
this.getCardLogin();
},
getCardLoginCallback: function(jqXHR, textStatus) {
if (textStatus !== "success") { return; }
this.releaseDevice();
},
releaseDeviceCallback: function(jqXHR, textStatus) {
if (textStatus !== "success") { return; }
//End
},
////////////////
// Other methods
////////////////
init: function() {
// UI BIndings
$(#button).on("click", this.logIn.bind(this));
},
logIn: function() {
this.lockDevice();
},
makeAjaxCall: function(callType, resource, callbackMethod) {
$.ajax({
type : callType,
url : "http://localhost:1337" + resource,
cache : false,
dataType : "json",
contentType: "application/json",
context : this,
complete : callbackMethod
});
}
};
答案 0 :(得分:1)
这可以满足您的需求,即使我不确定在这里完全理解您的问题。
这里的重点似乎是保持对ajax方法回调的顺序。你可以这样做:
创建这些方法:
_nextCall: function (deferreds, method) {
if (deferreds.length) this._when(deferreds, method);
else console.log(method + " SUCCESS");
},
_when: function (calls, method) {
var $promise = $.when(this[calls[0]]())
$promise.then(function () {
calls.splice(0, 1);
this._nextCall(calls, method);
}, function () {
console.log(method + " FAILED on: " + calls[0]);
});
},
像那样使用它:
logIn: function logIn() {
var calls = ["lockDevice", "getCardLogin", "releaseDevice"];
this._when(calls, arguments.callee.name);
},
getPinOnly: function getPinOnly() {
var calls = ["getPin"];
this._when(calls, arguments.callee.name);
},
完整代码:
var CardReader = {
////////////////////
// Different possible messages to the Card Reader
////////////////////
lockDevice: function () {
return this.makeAjaxCall("GET", "/LockDevice", this.lockDeviceCallback);
},
getCardLogin: function () {
return this.makeAjaxCall("POST", "/getCardLogin", this.getCardLoginCallback);
},
getPin: function () {
return this.makeAjaxCall("POST", "/getPin", this.getPinCallback);
},
releaseDevice: function () {
return this.makeAjaxCall("POST", "/Release", this.releaseDeviceCallback);
},
//////////////////
// Callbacks for each message to the Card Reader
//////////////////
lockDeviceCallback: function (jqXHR, textStatus) {
console.log("lockDeviceCallback");
if (textStatus !== "success") {
return;
}
},
getCardLoginCallback: function (jqXHR, textStatus) {
console.log("getCardLoginCallback");
if (textStatus !== "success") {
return;
}
},
getPinCallback: function (jqXHR, textStatus) {
console.log("getPinCallback");
if (textStatus !== "success") {
return;
}
},
releaseDeviceCallback: function (jqXHR, textStatus) {
console.log("releaseDeviceCallback");
if (textStatus !== "success") {
return;
}
//End
},
////////////////
// Other methods
////////////////
init: function () {
// UI BIndings
$('#btn_login').on("click", $.proxy(this.logIn, this));
$('#btn_getPinCallback').on("click", $.proxy(this.getPinOnly, this));
},
_nextCall: function (deferreds, method) {
if (deferreds.length) this._when(deferreds, method);
else console.log(method + " SUCCESS");
},
_when: function (calls, method) {
var $promise = $.when(this[calls[0]]())
$promise.then(function () {
calls.splice(0, 1);
this._nextCall(calls, method);
}, function () {
console.log(method + " FAILED on: " + calls[0]);
});
},
logIn: function logIn() {
var calls = ["lockDevice", "getCardLogin", "releaseDevice"];
this._when(calls, arguments.callee.name);
},
getPinOnly: function getPinOnly() {
var calls = ["getPin"];
this._when(calls, arguments.callee.name);
},
makeAjaxCall: function (callType, resource, callbackMethod) {
return $.ajax({
type: callType,
url: "/echo/json", // + resource,
cache: false,
dataType: "json",
contentType: "application/json",
context: this,
success: callbackMethod
});
}
};
CardReader.init();
答案 1 :(得分:1)
使用功能更全面的promises库。看看:https://github.com/kriskowal/q 值得花一点时间来理解,因为它极大地改善了代码的风格和可读性。基本上你可以编写每个业务函数,因此它返回一个promise,如下所示: -
function myBusinessFunction(params) {
var deferred = Q.defer();
....
doSomeAsyncFunction(params,function(error,result) {
if (error) {
deferred.reject(new Error(error)); //pass the error on
} else {
deferred.resolve(result);
}
});
return deferred.promise;
}
所以这里发生的是你创建一个函数的每个异步操作,在里面创建一个延迟并返回它。一旦出现超时或错误或任何结果,您就会调用deferred.reject或deferred.resolve。
通过添加代码,您可以避免回调地狱,其中有许多嵌套函数,并创建如下所示的整体算法代码: -
Q.fcall(promisedStep1)
.then(promisedStep2)
.then(promisedStep3)
.then(promisedStep4)
.then(function (value4) {
// Do something with value4
})
.catch(function (error) {
// Handle any error from all above steps
})
.done();
这非常类似于try ... catch程序样式编程,它非常熟悉,但实际上是在处理异步进程。当你在promise上调用reject时,控制流将传递给catch函数,大大简化了编程。
库中还有许多其他功能和特性,因此您可以并行处理运行步骤等。查看文档是值得的。
答案 2 :(得分:1)
阅读此jquery文档页面:
答案 3 :(得分:1)
使用Ajax调用尝试async: false
。这首先完成Ajax调用,然后执行其他语句。
makeAjaxCall:function(callType,resource,callbackMethod){
$.ajax({
type : callType,
url : "http://localhost:1337" + resource,
cache : false,
dataType : "json",
contentType: "application/json",
context : this,
async :false,
complete : callbackMethod
});
}
答案 4 :(得分:-1)
jQuery.support.cors = true;
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
datatype: "json",
async :false,
url: "http://yourHost:portnumeber/ServiceName/LockDevice",
success:
lockDeviceCallback,
error:
function (XmlHttpRequest, textStatus, errorThrown) {
errorHandler(XMLHttpRequest);
}
});