【问题标题】:JavaScript - ES6 function does not work for some weird reasonJavaScript - ES6 函数由于某些奇怪的原因无法工作
【发布时间】:2023-04-07 09:10:02
【问题描述】:

我正在设置以下函数以便在之后检索它。 但是,由于某种原因,它不起作用:

constructor(private nativeStorage: NativeStorage) {
    // I am calling it this way:
    this.userId = 123;
    this.getItem("userId", this.userId);

   // If I replace the shortcut by the below it works fine

   /* this.nativeStorage.getItem("userId).then(
        data => this.userId = data,
        error => console.error(error)
    ); */
}

getItem(itemKey, itemValue) {
  return this.nativeStorage.getItem(itemKey).then(
    data => itemValue = data,
    error => console.error(error)
  );
}

我相信我在这里遗漏了一些东西,这就是它不起作用的原因

【问题讨论】:

  • 你希望这个函数data => itemValue = data做什么?
  • 什么不起作用?
  • this.nativeStorage.getItem(itemKey) 是一个承诺?试试thencatch
  • itemValue 是一个局部变量。重新分配它在getItem() 之外没有任何影响。您是否尝试隐式更新this.userId
  • 然后查看@ibrahimmahrir 的答案。 JS 不支持类似的功能。除此之外,这还有另一个缺陷:this.nativeStorage.getItem() 是异步的。你不知道this.userId = data 的更新何时会发生。 100 毫秒(你几乎没有注意到)对于 JS 代码来说就像几个小时。除非您处理承诺,否则 this.userId 上的任何代码仍可能处理旧值。

标签: javascript function ecmascript-6


【解决方案1】:

您将data 分配给itemValue,这只是this.userId 的副本。 JS 不支持通过引用传递,这可能使之成为可能。相反,您可以像这样直接使用itemKey 分配给类实例:

getItem(itemKey) {
    return this.nativeStorage.getItem(itemKey).then(
        data => this[itemKey] = data, // assign data to this[itemKey] which will be this.userId (in the example above)
        error => console.error(error)
    );
}

【讨论】:

  • itemKey 是静态值,我也需要传递,ItemValue
  • @Folky.H 您没有使用它,因此无需通过它。加上itemKey 就足够了,如果你想要这个值,你可以使用this[itemKey] 访问它。
  • @Folky.H 这是由于this.nativeStorage.getItem() 的异步性质。 JS 不会等待 promise 解决,因此它可以记录更新的值。
  • 分配itemValue = data 转换为this.userId = data。那将是不支持的传递引用。
  • @Folky.H 不,这个构造函数不能按照你想要的方式工作;你不能有异步构造函数。由于这与此特定答案无关,因此让我们在问题本身的 cmets 中继续该主题。
【解决方案2】:

JavaScript 不支持引用调用。它只是通过值 arg 传递。所以值只能通过对象引用来更新。

【讨论】:

    【解决方案3】:

    参考不能有异步构造函数的部分/cmets,因此我将所有异步部分提取到工厂中。

    我还没有使用 ionic 的经验,所以您应该将以下内容作为伪代码:

    import { NativeStorage } from '@ionic-native/native-storage';
    
    function constructor(public userId: String){ }
    
    
    //and the factory function
    //don't know how exactly how to export stuff in that framework
    function createById(userId){
        return NativeStorage.getItem('userId')
            .then(
                userId => new YourClass(userId)
                error => console.error(error)
            )
    }
    

    或者在您想要分配多个属性的情况下:

    //a utility to resolve with { key: Promise<value> } mappings + pretty much everything you throw at it.
    //warning: doesn't resolve promises in nested structures (by design), 
    //stuff like {key: { foo: Promise<value> }}
    //ideally you'd put that in a seperate module since it can be handy in many places.
    function resolve(obj){
        if(Array.isArray(obj)
            return Promise.all(obj);
    
        if(typeof obj === "function")
            return Promise.resolve().then(obj);
    
        if(!obj || typeof obj !== "object" || "then" in obj && typeof obj.then === "function")
            return Promise.resolve(obj);
    
        var keys = Object.keys(obj);
        return Promise.all( keys.map(k => obj[k]) )
            .then(values => combine(keys, values));
    }
    
    //takes two Arrays, a matching set of keys and values and combines that into an object.
    function combine(keys, values){
        return keys.reduce((acc, key, index) => {
            acc[key] = values[index];
            return acc;
        }, {});
    }
    
    const assignTo = target => source => Object.assign(target, source);
    
    //in this case we use assign all async values outside of the constructor
    function constructor(){ 
        this.userId = null;
        this.userName = null;
    }
    
    function createById(userId){
        return resolve({
            userId: NativeStorage.getItem('userId'),
            userName: NativeStorage.getItem('userName'),
            //...
        }).then(
            assignTo( new YourClass() ),
            error => console.error(error)
        )
    }
    

    或者,如果这对你来说仍然有太多重复:

    //a utility to fetch multiple items at once 
    function getItems(...keys){
        return Promise.all( keys.map( key => NativeStorage.getItem(key) ) )
            .then(values => combine(keys, values));
    }
    
    //and a quick test
    getItems("userId", "userName", ...).then(console.log);
    
    //or in the context of the last snippet:
    getItems("userId", "userName", ...).then(assignTo( new YourClass() ));
    

    希望这有助于向您展示解决问题的不同方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-11-22
      • 1970-01-01
      • 2020-03-31
      • 2013-03-03
      • 2011-01-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多