如何异步地向诺言添加属性? [英] How to add properties to a promise asynchronously?

查看:61
本文介绍了如何异步地向诺言添加属性?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在此问题中:如何向诺言中添加自定义属性或方法?关于如何在预先知道属性的情况下将属性添加属性"到承诺函数 .

In this question : How to add a custom property or method to a promise? there are simple solutions regarding how to "add properties" to a promise function when the properties are known in advance.

对于 clientside-require 模块启用 require()函数加载的程序包,以将其自身的属性附加到 require()返回的承诺中.例如,要启用此功能:

For the clientside-require module I am attempting to enable packages that the require() function loads to append their own properties to the promise that require() returns. For example, to enable this:

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

或这个

var promies_request_package = require("clientside-request")
promies_request_package
    .request("https://google.com")
    .then((response)=>{
       console.log(response)
    })

问题在于,我们需要的每个软件包都应该能够定义自己的自定义属性.换句话说, 我们不同步了解属性 .首先,我们需要解决 promise_module_properties ,然后根据这些属性,必须修改 require 产生的诺言的属性.

The problem is that each of these packages we are requiring should be able to define their own custom properties. In other words, we do not know the properties synchronously. First we need to resolve promise_module_properties and then based on those properties the properties of the promise produced by require must be modified.

这可能吗?

推荐答案

正如Bergi所说,仅仅因为我们可以做到这一点并不意味着我们应该.实际上,我强烈建议您反对.

As Bergi noted, just because we can do this does not mean we should. In fact, i highly recommend against it.

无论如何,都可以使用生成器和代理:

Regardless, it is possible using a builder and a proxy:

假定属性的异步定义如下:

Assume the properties are asynchronously defined as follows:

var properties_to_append = {
    load : function(path){
        return this.then((view_loader)=>{ console.log("loading " + path); return view_loader.load(path)}) // define `view_loader.load()` to the view_loader promise
    },
    generate : function(options){
        return this.then((compiler)=>{ return compiler.generate(options) })
    },
}
var promise_properties = Promise.resolve(properties_to_append);

然后利用定义的 AsyncPropertyPromise 类进一步按预期进行以下工作:

Then utilizing the AsyncPropertyPromise class defined further down the following works as expected:

var async_property_promise = new AsyncPropertyPromise(require("clientside-view-loader"), promise_properties);
async_property_promise // works
    .load("clientside-view-modal-login_signup") // works
    .generate() // works
    .then((modal)=>{
        document.body.appendChild(modal);
        modal.show("login");
    })

AsyncPropertyPromise:

AsyncPropertyPromise:

var unknown_properties_deferment_handler = {
    return_defined_target_value : function(target, prop){
        var value = target[prop];
        var bound_value = typeof value == 'function' ? value.bind(target) : value; // bind functions to target, as they would expect
        return bound_value; // return the requested name or parameters
    },
    get: function(target, prop) {
        if(prop in target){
            return this.return_defined_target_value(target, prop); // if the requested method or parameter is in the target object, just return it
        } else {
            return target.promise_to_attempt_to_get_async_property(prop);
        }
    }
};

class AsyncPropertyPromise {
    constructor(original_promise, promise_properties) {
        this.original_promise = original_promise;
        this.promise_properties = promise_properties;
        var proxied_self = new Proxy(this, unknown_properties_deferment_handler);
        return proxied_self;
    }
    then(...args) {
        return this.original_promise.then(...args);
    }
    catch(...args){
        return this.original_promise.catch(...args);
    }
    promise_to_attempt_to_get_async_property(property){
        /*
            1. return a function - NOTE - this assumes that any property not statically defiend is a function
            2. make that function resolve with an AsnycPropertyPromise that
                a. returns the value of the property (method) if it exists
                b. throws error if it does not
        */
        return function(...args){ // 1
            var raw_response_promise = this.promise_properties // 2
                .then((loaded_properties)=>{
                    if(!(property in loaded_properties)) throw "property not defined"; // 2.a
                    var value = loaded_properties[property];
                    var bound_value = value.bind(this); // bind to original_promise
                    return bound_value(...args); // evaluate and return response while passing orig arguments; see `spread` https://stackoverflow.com/a/31035825/3068233
                });
            var async_proxied_response_promise = this._wrap_a_promise(raw_response_promise);
            return async_proxied_response_promise;
        }
    }
    _wrap_a_promise(raw_promise){
        return new this.constructor(raw_promise, this.promise_properties);
    }
}

这篇关于如何异步地向诺言添加属性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆