【问题标题】:Best practice: Javascript Classes depending on asynchronously fetching external data [closed]最佳实践:依赖于异步获取外部数据的 Javascript 类 [关闭]
【发布时间】:2021-05-12 03:50:32
【问题描述】:

我的 javascript 技能有点过时了,所以我想咨询你的最佳实践建议。

我想要达到的目标:

  • 创建一个封装从外部服务获取的 JSON 的类
  • 创建另一个类,作为封装所有网络内容的前类的工厂
  • 了解如何处理 Promise

这是草稿:

class DataObject {
  constructor(json) {...}
  someMethod() {...}
}

class DataObjectFactory {
  constructor() {...}
  getDataObject(id) {
     ..fetch(url)..
  }
}

myDataObjectFactory.getDataObject(123).then(...)

现在,我可以强制 getDataObject() 同步行动,但我想了解在这种情况下使用 Promise 的最佳方式是什么。我如何组织和编写我的东西以确保 DataObject 成功填充 JSON 数据?

也欢迎提供有用的操作指南的链接。

谢谢!

【问题讨论】:

  • 欢迎来到 S.O! myDataObjectFactory.getDataObject(123).then(...) 的结果是否被 DataObject 使用?
  • 谢谢!不,它应该构建并返回一个 DataObject

标签: javascript node.js express asynchronous


【解决方案1】:

对于fetch 及其方法已经提供的内容,没有什么可补充的。但它可能如下所示。这个 sn-p 使用 JSONPlaceholder 来获取一些数据:

class DataObject {
  constructor(obj) {
    Object.assign(this, obj);  
  }
  toString() {
    return `User ${this.userId} ${this.completed ? "completed" : "did not yet complete"} the task number ${this.id}, labeled '${this.title}'`;
  }
}

class DataObjectFactory {
  constructor() {
  }
  async getDataObject(id) {
     let response = await fetch("https://jsonplaceholder.typicode.com/todos/" + id);
     let obj = await response.json();
     return new DataObject(obj);
  }
}

let myDataObjectFactory = new DataObjectFactory();
myDataObjectFactory.getDataObject(123).then(myDataObject =>
    console.log(myDataObject.toString())
);

没有async await 的版本看起来像这样:

class DataObject {
  constructor(obj) {
    Object.assign(this, obj);  
  }
  toString() {
    return `User ${this.userId} ${this.completed ? "completed" : "did not yet complete"} the task number ${this.id}, labeled '${this.title}'`;
  }
}

class DataObjectFactory {
  constructor() {
  }
  getDataObject(id) {
     return fetch("https://jsonplaceholder.typicode.com/todos/" + id)
          .then(response => response.json())
          .then(obj => new DataObject(obj));
  }
}

let myDataObjectFactory = new DataObjectFactory();
myDataObjectFactory.getDataObject(123).then(myDataObject =>
    console.log(myDataObject.toString())
);

【讨论】:

    【解决方案2】:

    如果你想直接使用 Promise,你可以让你的 getDataObject() 返回在 fetch 解析后解析的 Promise。 当您调用 getDataObject().then() 时,请给出函数或 lambda 表达式下一步该做什么。

    class DataObjectFactory {
      constructor() {...}
      
      getDataObject(id) {
        let getDataObjectPromise = new Promise(function(resoveFn) {
            fetch(url).then(
                resoveFn(
                    DataObject(response)
                )
            );
        });
        return getDataObjectPromise;
      }
    }
    
    
    function useDataObject(newDataObject){
        // there you can use DataObject
    }
    
    myDataObjectFactory.getDataObject(123).then(useDataObject); //use function or lambda expression
    

    如果你想使用自然的语法,你可以使用 async/await,它在表面下使用 promise

    class DataObjectFactory {
      constructor() {...}
      async getDataObject(id) {
         let json = await fetch(url);
         return DataObject(json);
      }
    }
    
    async function getAndUseDataObject(){
        var myDataObject = await myDataObjectFactory.getDataObject(123);
        // use myDataObject like in sync function
    }
    
    getAndUseDataObject(); //One can't use await outside async function
    

    【讨论】:

    猜你喜欢
    • 2019-08-24
    • 2010-10-04
    • 2021-01-11
    • 1970-01-01
    • 2013-04-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-14
    相关资源
    最近更新 更多