在Prototype方法中调用嵌套函数并返回Promise

时间:2018-04-09 17:09:04

标签: javascript promise prototype

用例:我的用户需要一个相对简单的点符号,它也可以处理大量的异步性。我一直在修补一种最有可能陷入封闭的模式。该模式包括:

  1. 初始功能定义
  2. 原型方法声明
  3. 原型中通常会返回值或承诺的函数。
  4. 结果:我希望用户能够以下列格式访问这些方法:

    ParentFunction.prototype_method.nested_function(参数);

    问题 现在我看到各种未定义的问题,因为我设计这是一个相当大的API实现,我不确定这种模式是否最合适。由于我来自Java背景,如果可能的话,我更喜欢这种方法,而我的最终目标是尽可能让初级用户可以阅读和访问API。

    示例来源

    //Parent function
    var Actor = function(model, timings, options) {
      this.model = {
        "node": node
      };
    
      this.timings = timings;
      this.options = options;
    };
    
    //Sample prototype method
    Actor.prototype.eventController = function() {
        var self = this;
    
        var clickEvent = function() {
          return new Promise(function(resolve, reject) {
            setTimeout(function() {
              try {
                $(self.model.node).trigger('click');
                resolve(true);
              } catch (error) {
                resolve(false);
              }
            }, self.timings.click);
          });
        }
    
        var mouseOverEvent = function() {
          return new Promise(function(resolve, reject) {
            setTimeout(function() {
              try {
                $(self.model.node).trigger('mouseover');
                resolve(true);
              } catch (error) {
                resolve(false);
              }
            }, self.timings.mouseover);
          });
        }
    
    //Instantiate parent function
    var actor = new Actor();
    
    //Access nested function within prototype method then handle promise result
    actor.eventController.clickEvent.then(...);
    

1 个答案:

答案 0 :(得分:0)

如果您的构造函数设置了您需要的属性,而不是搞乱原型,那该怎么办?

// dummy version for testing
const $ = (elt) => ({trigger: function(evt) {console.log(`${evt} on ${elt}`)}})

const makeHandler = (obj, evtName) => () => new Promise((resolve, reject) => {
  setTimeout(() => {
    try {
      $(obj.model.node).trigger(evtName);
      resolve(true);
    } catch(error) {
      resolve(false);
    }
  }, obj.timings[evtName]);
});

function Actor(foo) {
  this.model = {node: foo};
  // don't know where these would come from.  Hard-coding here.
  this.timings = {
    click: 150,
    mouseover: 100
  };
  this.eventController = {
    clickEvent: makeHandler(this, 'click'),
    mouseOverEvent: makeHandler(this, 'mouseover')
  } 
}

var actor1 = new Actor('abc');
var actor2 = new Actor('def');

actor1.eventController.clickEvent().then(console.log, console.log);
actor2.eventController.mouseOverEvent().then(console.log, console.log);

您也可以用工厂函数替换它:

function actor(foo) {
  const obj = {
    model: {node: foo},
    timings: {
      click: 150,
      mouseover: 100
    }
  };
  obj.eventController = {
    clickEvent: makeHandler(obj, 'click'),
    mouseOverEvent: makeHandler(obj, 'mouseover')
  };
  return obj; 
}

var actor1 = actor('abc');
var actor2 = actor('def');

(当然,这可以通过ES6箭头功能清理一下。)