admin管理员组文章数量:1335543
Regular promises have the beloved .then()
and .catch()
functions.
When promising
to retrieve an object that itself has properties that return promises we find chains of promises such as the following:
require("clientside-view-loader")
.then((view)=>
return view.load("clientside-view-modal-login_signup");
})
.then((piler)=>{
return piler.generate()
})
.then((modal)=>{
document.body.appendChild(modal);
modal.show("login");
})
This is UGLY!
How can we modify a promise to attach a custom property so that we can convert the above into the following?
require("clientside-view-loader")
.load("clientside-view-modal-login_signup")
.generate()
.then((modal)=>{
document.body.appendChild(modal);
modal.show("login");
})
note, these examples use the clientside-require
require
and not the nodejs
require
Regular promises have the beloved .then()
and .catch()
functions.
When promising
to retrieve an object that itself has properties that return promises we find chains of promises such as the following:
require("clientside-view-loader")
.then((view)=>
return view.load("clientside-view-modal-login_signup");
})
.then((piler)=>{
return piler.generate()
})
.then((modal)=>{
document.body.appendChild(modal);
modal.show("login");
})
This is UGLY!
How can we modify a promise to attach a custom property so that we can convert the above into the following?
require("clientside-view-loader")
.load("clientside-view-modal-login_signup")
.generate()
.then((modal)=>{
document.body.appendChild(modal);
modal.show("login");
})
note, these examples use the clientside-require
require
and not the nodejs
require
3 Answers
Reset to default 6How can we modify a promise to attach a custom property so that we can convert the above into the following?
You don't modify promises at all. You just implement the builder pattern for the above promise chain.
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(piler =>
piler.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");
})
No need to do anything plicated like subclassing Promise
. If you want, you can also dynamically generate all these methods.
This is UGLY!
Well, if you were looking for beautiful promise code, you would simply use modern async
/await
syntax instead of then
callbacks:
const view = await require("clientside-view-loader");
const piler = await view.load("clientside-view-modal-login_signup");
const modal = await piler.generate();
document.body.appendChild(modal);
modal.show("login");
Your initial code can be made shorter and more readable simply by using different syntax for your arrow functions. These two rules of arrow function syntax are relevant:
- parentheses are optional around the only argument of single-argument functions
- single-statement functions that return a value can have the
{}
and thereturn
removed
Thus, you could write your code like this, with the short form view => …
instead of (view) => { return …; }
:
require("clientside-view-loader")
.then(view => view.load("clientside-view-modal-login_signup"))
.then(piler => piler.generate())
.then(modal => {
document.body.appendChild(modal);
modal.show("login");
});
If you know the properties you wish to add in advance you can simply append a property to the promise like you would any other object:
view_loader.load = function(path){
return this.then((view_loader)=>{
return view_loader.load(path)
})
}
view_loader.load(...) // now works!
Here's a function that does this for a dynamic set of properties:
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;
}
Then
var properties_to_append = {
load : function(path){
return this.then((view_loader)=>{ return view_loader.load(path)})
}
}
modified_require = modify_orig_promise(require("clientside-view-loader"), properties_to_append);
modified_require.load("clientside-view-modal-login_signup") // Works
If you dont know the properties in advance (e.g., the properties are determined from a promise) you'll need to use a proxy that waits until that promise resolves to respond. This is answered here: How to add properties to a promise asynchronously?
本文标签: javascriptHow to add a custom property or method to a promiseStack Overflow
版权声明:本文标题:javascript - How to add a custom property or method to a promise? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742386134a2465068.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论