Javascript 如何向承诺添加自定义属性或方法?

Javascript 如何向承诺添加自定义属性或方法?,javascript,asynchronous,promise,Javascript,Asynchronous,Promise,定期的承诺有爱人。然后和。捕捉功能 当承诺检索本身具有返回承诺的属性的对象时,我们会发现承诺链,例如: require("clientside-view-loader") .then((view)=> return view.load("clientside-view-modal-login_signup"); }) .then((compiler)=>{ return compiler.generate() })

定期的承诺有爱人。然后和。捕捉功能

当承诺检索本身具有返回承诺的属性的对象时,我们会发现承诺链,例如:

require("clientside-view-loader")
    .then((view)=>
        return view.load("clientside-view-modal-login_signup");
    })
    .then((compiler)=>{
        return compiler.generate()
    })
    .then((modal)=>{
        document.body.appendChild(modal);
        modal.show("login");
    })
这太难看了

如何修改承诺以附加自定义属性,以便将上述内容转换为以下内容

require("clientside-view-loader")
    .load("clientside-view-modal-login_signup")
    .generate()
    .then((modal)=>{
        document.body.appendChild(modal);
        modal.show("login");
    })

注意,这些示例使用require而不是nodejs require

如果您事先知道要添加的属性,您可以像添加任何其他对象一样简单地将属性附加到promise:

view_loader.load = function(path){
    return this.then((view_loader)=>{
        return view_loader.load(path)
    })
}
view_loader.load(...) // now works!
下面是一个函数,它对一组动态属性执行此操作:

function modify_orig_promise(original_promise, properties_to_append){
    var blacklist = ["then", "catch", "spread"];
    var function_keys = Object.keys(properties_to_append);
    for(var i = 0; i < function_keys.length; i++){
        var function_key = function_keys[i];
        if(blacklist.indexOf(function_key) > -1) {
            console.warn("properties_to_append in require(__, {functions : {} }) included a blacklisted function name : `"+key+"`. skipping this property.")
        } else {
            var requested_function = properties_to_append[function_key];
            original_promise[function_key] = requested_function; // append the function to the promise
        }
    }
    return original_promise;
}

如果您事先不知道属性,例如,属性是根据承诺确定的,那么您需要使用一个代理,等待该承诺解决后才能响应。这里的答案是:

如果您事先知道要添加的属性,您可以像添加任何其他对象一样简单地将属性附加到承诺中:

view_loader.load = function(path){
    return this.then((view_loader)=>{
        return view_loader.load(path)
    })
}
view_loader.load(...) // now works!
下面是一个函数,它对一组动态属性执行此操作:

function modify_orig_promise(original_promise, properties_to_append){
    var blacklist = ["then", "catch", "spread"];
    var function_keys = Object.keys(properties_to_append);
    for(var i = 0; i < function_keys.length; i++){
        var function_key = function_keys[i];
        if(blacklist.indexOf(function_key) > -1) {
            console.warn("properties_to_append in require(__, {functions : {} }) included a blacklisted function name : `"+key+"`. skipping this property.")
        } else {
            var requested_function = properties_to_append[function_key];
            original_promise[function_key] = requested_function; // append the function to the promise
        }
    }
    return original_promise;
}
如果您事先不知道属性,例如,属性是根据承诺确定的,那么您需要使用一个代理,等待该承诺解决后才能响应。答案如下:

如何修改承诺以附加自定义属性,以便将上述内容转换为以下内容

require("clientside-view-loader")
    .load("clientside-view-modal-login_signup")
    .generate()
    .then((modal)=>{
        document.body.appendChild(modal);
        modal.show("login");
    })
你根本不会改变承诺。您只需为上述承诺链实现构建器模式

class ClientSideViewLoader {
  constructor(p = Promise.resolve()) {
    this.promise = p;
  }
  static init() {
    return new this(require("clientside-view-loader"));
  }
  load(x) {
    return new this.constructor(this.promise.then(view =>
      view.load(x)
    ));
  }
  generate() {
    return new this.constructor(this.promise.then(compiler => 
      compiler.generate()
    ));
  }
  then(...args) {
    return this.promise.then(...args);
  }
}

ClientSideViewLoader.init()
.load("clientside-view-modal-login_signup")
.generate()
.then(modal => {
  document.body.appendChild(modal);
  modal.show("login");
})
不需要做任何复杂的事情,比如子类化Promise。如果需要,还可以动态生成所有这些方法

这太难看了

如果您正在寻找漂亮的promise代码,只需使用现代的async/await语法,而不是回调:

const view = await require("clientside-view-loader");
const compiler = await view.load("clientside-view-modal-login_signup");
const modal = await compiler.generate();
document.body.appendChild(modal);
modal.show("login");
如何修改承诺以附加自定义属性,以便将上述内容转换为以下内容

require("clientside-view-loader")
    .load("clientside-view-modal-login_signup")
    .generate()
    .then((modal)=>{
        document.body.appendChild(modal);
        modal.show("login");
    })
你根本不会改变承诺。您只需为上述承诺链实现构建器模式

class ClientSideViewLoader {
  constructor(p = Promise.resolve()) {
    this.promise = p;
  }
  static init() {
    return new this(require("clientside-view-loader"));
  }
  load(x) {
    return new this.constructor(this.promise.then(view =>
      view.load(x)
    ));
  }
  generate() {
    return new this.constructor(this.promise.then(compiler => 
      compiler.generate()
    ));
  }
  then(...args) {
    return this.promise.then(...args);
  }
}

ClientSideViewLoader.init()
.load("clientside-view-modal-login_signup")
.generate()
.then(modal => {
  document.body.appendChild(modal);
  modal.show("login");
})
不需要做任何复杂的事情,比如子类化Promise。如果需要,还可以动态生成所有这些方法

这太难看了

如果您正在寻找漂亮的promise代码,只需使用现代的async/await语法,而不是回调:

const view = await require("clientside-view-loader");
const compiler = await view.load("clientside-view-modal-login_signup");
const modal = await compiler.generate();
document.body.appendChild(modal);
modal.show("login");

您的初始代码可以变得更短,更易于阅读,只需为您的应用程序使用不同的语法即可。箭头函数语法的这两个规则是相关的:

单参数函数的唯一参数周围的括号是可选的 返回值的单语句函数可以删除{}和返回值 因此,您可以这样编写代码,使用缩写形式view=>…而不是view=>{return…;}:

RequiredClient侧视图加载程序 .thenview=>view.loadclientside-view-modal-login\u注册 .thencompiler=>compiler.generate .thenmodal=>{ document.body.appendChildmodal; modal.showlogin; };
您的初始代码可以变得更短,更易于阅读,只需为您的应用程序使用不同的语法即可。箭头函数语法的这两个规则是相关的:

单参数函数的唯一参数周围的括号是可选的 返回值的单语句函数可以删除{}和返回值 因此,您可以这样编写代码,使用缩写形式view=>…而不是view=>{return…;}:

RequiredClient侧视图加载程序 .thenview=>view.loadclientside-view-modal-login\u注册 .thencompiler=>compiler.generate .thenmodal=>{ document.body.appendChildmodal; modal.showlogin; };
如果箭头函数需要返回一个对象文字,但需要使用括号:x=>{someProp:x}如果箭头函数需要返回一个对象文字,但需要使用括号:x=>{someProp:x}我是否可以从承诺中解析这个构建器类ClientSideViewLoader?e、 例如,requireclientside视图加载程序解析ClientSideViewLoader.init?我的问题是load和generate方法是异步定义的。@UladCasach当然可以创建一个直接返回生成器实例的模块。但是我不确定你所说的异步是什么意思-不,构建器方法必须从一开始就定义,否则构建器调用将需要放在承诺链中-毫无意义。我已经在澄清了我的问题,因为我在这个线程的原始问题中过于笼统。你能看一下吗?不管怎样,我可以从一个承诺中解析这个构建器类ClientSideViewLoader吗?e、 例如,requireclientside视图加载程序解析ClientSideViewLoader.init?我的问题是load和generate方法是异步定义的。@UladCasach当然可以创建一个直接返回生成器实例的模块。但是我不确定异步是什么意思-不,构建器方法必须从一开始就定义,否则构建器调用w
你需要被放在一个承诺链中——这是毫无意义的。我已经在上澄清了我的问题,因为我在这个问题上的原始问题太笼统了。你能看一下吗?