【问题标题】:Working with office.js using promise pattern使用 promise 模式使用 office.js
【发布时间】:2015-04-20 09:47:58
【问题描述】:

目前我已经开始开发一些适用于 Office 2013 的应用程序。为了开发这些应用程序,我使用了 office.js,它旨在与 Excel 工作表一起使用。

大部分 API 如下:

document.getSelectedDataAsync(p1, p2, function(asyncResult)
{
    if (asyncResult.status == 'success')
        // do something with asyncResult.value
    else if (asyncResult.status == 'fail')
        // show asyncResult.error as Error
});

我不喜欢这种异步编程。相反,我更喜欢使用 promises 并编写如下内容:

document.getSelectedDataAsync(p1, p2)
    .done(function(result)
    {
        // do something with result
    })
    .fail(function(error)
    {
        // show error message 
    })

有没有办法通过上面的 Promise 来使用 office.js API?

【问题讨论】:

    标签: javascript promise office-2013 office-app


    【解决方案1】:

    当然——这个例子使用了the bluebird promise 库。基本上,我们将回调 API 转换为 Promise:

    function promisify(fn){ // take a function and return a promise version
         return function(){
              var args = [].slice.call(arguments);
              return new Promise(function(resolve, reject){
                   args.push(function(asyncResult){
                        if(asyncResult.status === 'success') resolve(asyncResult.value);
                        else reject(asyncResult.error);
                   }); 
                   fn.apply(this, args); // call function   
              }.bind(this)); // fixate `this`
         };
    }
    

    这会让你做类似的事情:

    document.getSelectedDataPromise = promisify(document.getSelectedDataAsync);
    document.getSelectedDataPromise(p1, p2).then(function(result){
       // do something with result
    }).catch(function(err){
       // handle error
    });
    

    【讨论】:

      【解决方案2】:

      解决此问题的最简单形式是将回调替换为可解决承诺的自定义回调。请注意,以下实现使用了 Chrome 中可用的 ES6 承诺:

              function toPromise () {
                  var args = Array.prototype.slice.call(arguments);
                  var self = this;
                  return new Promise(function (reject, resolve) {
                      var callback = function () {
                          if (arguments[0] instanceof Error) {
                              return reject.apply(null, arguments);
                          }
      
                          resolve.apply(arguments);
                      };
      
                      args.push(callback);
                      self.apply(self, args);
                  });
              }
      
              Function.prototype.toPromise = toPromise;
      
              document.getSelectedDataAsync.toPromise(p1, p2).then(function () {
                  //success
              }).catch(function () {
                  //error
              });
      

      【讨论】:

      • 谢谢,但我没有使用 ES 6。我正在寻找一种更简单的方法,也许是一个可以实现这一点的库。就像 jQuery 的新版本支持他们的 ajax 调用的承诺模式。
      • 你可以用你喜欢的任何东西替换承诺。如果不存在这样的库,那么您应该考虑自己做。
      • 解决方案总是单一的。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-03-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-07
      • 1970-01-01
      相关资源
      最近更新 更多