1)in removeEventHandlers
,cb()总是会在删除所有监听器后执行?
号这将去除的开始后调用。但是,如果删除是异步的,则可以在删除完成之前调用它。
2)我是否必须将addEventHandlers
作为removeEventHandlers
的回调以确保其执行顺序?
是的,但不是你拥有的方式。你的方式就像是在做
removeEventHandlers();
addEventHandlers();
,因为你叫cb
在removeEventHandlers
年底,而无需等待任何东西到结束。
由于removeHandlerAsync
和releaseByIdAsync
都建有callback
而非promise
,我需要callback
来组织整个代码。
或者你可以给自己的Promise版本。更多关于这一点。
使用非无极回调方法,以确保您从removeEventHandlers
调用cb
当所有工作完成后,记得你有多少回调期待和等待,直到你得到很多之前调用cb
:
var oldBindings = ["myBind1", "myBind2"]; // can be updated by other functions
function updateEventHandlers(newBindings) {
removeEventHandlers(oldBindings, function() {
addEventHandlers(newBindings);
});
}
function removeEventHandlers(oldBindings, cb) {
var waitingFor = oldBindings.length;
for (var i = 0; i < oldBindings.length; i++) {
Office.select("binding#"+oldBindings[i]).removeHandlerAsync(Office.EventType.BindingDataChanged, function (asyncResult) {
Office.context.document.bindings.releaseByIdAsync(oldBindings[i], function() {
if (--waitingFor == 0) {
cb();
}
});
});
}
}
但你有一个回调系统任何时候,你能答应,IFY它:
function removeHandlerPromise(obj, eventType) {
return new Promise(function(resolve, reject) {
obj.removeHandlerAsync(eventType, function(asyncResult) {
if (asyncResult.status == Office.AsyncResultStatus.Failed) {
reject(asyncResult.error);
} else {
resolve(asyncResult.value);
}
});
});
}
function releaseByIdPromise(obj, value) {
return new Promise(function(resolve, reject) {
obj.releaseByIdAsync(value, function(asyncResult) {
if (asyncResult.status == Office.AsyncResultStatus.Failed) {
reject(asyncResult.error);
} else {
resolve(asyncResult.value);
}
});
});
}
然后,让你这样做:
var oldBindings = ["myBind1", "myBind2"]; // can be updated by other functions
function updateEventHandlers(newBindings) {
removeEventHandlers(oldBindings).then(function() {
addEventHandlers(newBindings);
});
}
function removeEventHandlers(oldBindings) {
return Promise.all(oldBindings.map(function(binding) {
return removeHandlerPromise(Office.select("binding#"+binding), Office.EventType.BindingDataChanged).then(function() {
return releaseByIdPromise(Office.context.document.bindings, binding);
});
});
}
或者你可以给自己一个通用的承诺,ifier任何异步运算返回一个AsyncResult
:然后
function promisify(obj, method) {
var args = Array.prototype.slice.call(arguments, 2);
return new Promise(function(resolve, reject) {
args.push(function(asyncResult) {
if (asyncResult.status == Office.AsyncResultStatus.Failed) {
reject(asyncResult.error);
} else {
resolve(asyncResult.value);
}
});
obj[method].apply(obj, args);
});
}
,可以让你做到这一点:
var oldBindings = ["myBind1", "myBind2"]; // can be updated by other functions
function updateEventHandlers(newBindings) {
removeEventHandlers(oldBindings).then(function() {
addEventHandlers(newBindings);
});
}
function removeEventHandlers(oldBindings) {
return Promise.all(oldBindings.map(function(binding) {
return promisify(Office.select("binding#"+binding), "removeHandlerAsync", Office.EventType.BindingDataChanged).then(function() {
return promisify(Office.context.document.bindings, "releaseByIdAsync", binding);
});
});
}
同意关于包装回调到一个承诺,如果它使你的代码逻辑更容易。 –
真的很不错的教程...谢谢... – SoftTimur