2017-03-17 118 views
1

我有一個變量oldBindings,它記錄了Excel表的所有現有綁定。我已經根據oldBindings建立了BindingDataChanged位聽衆。因此,當newBindings出現時,我需要刪除鏈接到oldBindings的所有舊聽衆,並根據newBindings添加新聽衆。目前,我寫了下面的代碼:循環中的異步回調

var oldBindings = ["myBind1", "myBind2"]; // can be updated by other functions 

function updateEventHandlers(newBindings) { 
    removeEventHandlers(oldBindings, function() { 
     addEventHandlers(newBindings) 
    }) 
} 

function removeEventHandlers(oldBindings, cb) { 
    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() {}); 
     }); 
    } 
    cb() 
} 

由於removeHandlerAsyncreleaseByIdAsynccallback而不是promise建,我需要callback來組織整個代碼。有兩件事我不確定:

1)in removeEventHandlers,will cb()總是在刪除所有聽衆後執行?我怎麼能確保?

2)我是否必須將addEventHandlers作爲callbackremoveEventHandlers以確保其執行順序?

回答

2

1)in removeEventHandlers,cb()總是會在刪除所有監聽器後執行?

號這將去除的開始後調用。但是,如果刪除是異步的,則可以在刪除完成之前調用它。

2)我是否必須將addEventHandlers作爲removeEventHandlers的回調以確保其執行順序?

是的,但不是你擁有的方式。你的方式就像是在做

removeEventHandlers(); 
addEventHandlers(); 

,因爲你叫cbremoveEventHandlers年底,而無需等待任何東西到結束。

由於removeHandlerAsyncreleaseByIdAsync都建有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); 
     }); 
    }); 
} 
+0

同意關於包裝回調到一個承諾,如果它使你的代碼邏輯更容易。 –

+0

真的很不錯的教程...謝謝... – SoftTimur