简体   繁体   English

我应该在每个类方法中创建一个新的Promise吗?

[英]Should I create a new Promise in each class method?

I would like to utilize the Promises in my class methods. 我想在我的类方法中使用Promises。 In Promise antipatterns I read that creating a new promise for each new function is considered to be bad. Promise反模式中,我读到为每个新函数创建一个新的承诺被认为是坏的。

However, I don't want to return un-related promises in my project, so I thought of doing something like this: 但是,我不想在我的项目中返回不相关的promise,所以我想做这样的事情:

class MyClass {

  async getToken() {
    return new Promise(
      (resolve, reject) => {
        // . . .
        const token_str = '<response_from_http_request>';
        resolve(token_str);
      }
    )
  }

  async doSomething(token) {
    return new Promise(
      (resolve, reject) => {
        const result = // . . .
        resolve(result);
      }
    )
  }

  async doAnotherSomething(token) {
    return new Promise(
      (resolve, reject) => {
        const result = // . . .
        resolve(result);
      }
    )
  }

}

Then I would use it like this: 然后我会像这样使用它:

let instance = new MyClass();

(async () => {
    const token = await instance.getToken();

    const result1 = await instance.doSomething(token);
    console.log(result1);

    const result2 = await instance.doAnotherSomething(token);
    console.log(result2);

})();

Does this seem like a valid way to do this, or is this an antipattern too? 这看起来像是一种有效的方法吗,或者这也是一个反模式? And if so, how can I avoid writing code like this? 如果是这样,我怎么能避免编写这样的代码?


EDIT: What if I need to make several sequential http calls, perform some actions on the results and then return a Promise based on it? 编辑:如果我需要进行几个连续的http调用,对结果执行一些操作然后返回基于它的Promise怎么办?

The way I understand, if I don't make a new Promise, I have to return the one made by the got.js library, which includes the http response data. 我理解的方式,如果我不做一个新的 Promise,我必须返回由got.js库创建的,包括http响应数据。

Instead, I want to return a Promise which contains the result of my class method. 相反,我想返回一个包含我的类方法结果的Promise。

Example: 例:
  async getCityWeather( city_name ) { return new Promise( (resolve, reject) => { // get the city id based on its name const city_id = await got(`https://my-api/getCityIdByName/${city_name}`); // now get the weather info for the city with id `cityid` const weather_info = await got(`https://my-api/weatherById/${city_id}`); // make an object to return const temperature = { weather_info.temp_min, weather_info.temp_max, } resolve(temperature); // ... all error handling are omitted } ) } 

I don't want to return a Promise that contains got.js return values, I want to return my values based on the http request calls. 我不想返回包含got.js返回值的Promise,我想根据http请求调用返回我的值。

async functions always return a Promise . async函数总是返回一个Promise

A function/method will return a Promise under the following circumstances: 在以下情况下,函数/方法将返回Promise:

  • You explicitly created and returned a Promise from it's body. 你明确地创建并从它的身体返回了一个Promise。
  • You returned a Promise that exists outside the method. 您返回了一个存在于方法之外的Promise。
  • You marked it as async . 您将其标记为async

Since you can await a Promise and instance.doSomething is already an async-marked method, you can await it without needing to explicitly return a Promise. 因为您可以await Promise和instance.doSomething已经是异步标记的方法,您可以等待它而无需显式返回Promise。

Simply return it's result like you would in a regular synchronous method. 只需return它的结果,就像在常规同步方法中一样。

I don't want to return un-related promises in my project... 我不想在我的项目中返回不相关的承诺......

Unless you're actually doing something asynchronous in your method (accessing the file system, database calls, timers etc...), you don't need to wrap it in a Promise , nor await it when you need a result. 除非您实际上在方法中执行异步操作(访问文件系统,数据库调用,计时器等...), 否则不需要将其包装在Promise ,也不需要在需要结果时await它。

The most usual case where you actually need to wrap something in a Promise is if you have an asynchronous function that works using callbacks but you want to use it as a Promise . 实际上需要在Promise包装内容的最常见情况是,如果你有一个使用回调函数的异步函数,但你想将它用作Promise

 // plain old callback-style asynchronous functions: const getFooViaCallback = callback => { setTimeout(() => { callback('foo') }, 150) } const getBarViaCallback = callback => { setTimeout(() => { callback('bar') }, 150) } class Foo { constructor() {} getFooViaPromise() { // wrap callback-style code in a Promise // so we can await it. return new Promise(resolve => { getFooViaCallback(result => { resolve(result) }) }) } getBarViaPromise() { // wrap callback-style code in a Promise // so we can await it. return new Promise(resolve => { getBarViaCallback(result => { resolve(result) }) }) } getBaz() { // no reason to wrap this in a Promise, // since it's a synchronous method. return 'baz' } async getFooBarBaz() { const foo = await this.getFooViaPromise() const bar = await this.getBarViaPromise() const baz = this.getBaz() return foo + ',' + bar + ',' + baz } } ;(async() => { const foo = new Foo() const result = await foo.getFooBarBaz() console.log('foo.getFooBarBaz() result: ', result) })() 

I've ommited error handling in the above snippet for brevity but you should use throw in async -marked methods to raise errors. 为简洁起见,我在上面的代码段中省略了错误处理,但你应该使用throw in async -marked方法来引发错误。 It's the equivalent of calling .reject() within a Promise. 这相当于在Promise中调用.reject()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 应该由Promise调用同步代码。然后创建一个新的Promise - Should synchronous code called by Promise .then create a new Promise 是否应该为每个连接创建一个新的Redis客户端? - Should I create a new Redis client for each connection? 我可以创建一个可供创建对象的每个属性使用的类方法吗? - Can I create a class method usable by each property of an created object? 我应该使用Promise.All而不是async.each吗? - Should I use Promise.All instead of async.each? 如何创建新的承诺? - How to create a new promise? 我应该在等待事件发生时明确地创建一个承诺吗? - Should I explicitly create a promise when waiting for an event to fire? 每次单击都会创建新按钮。 我应该如何为新创建的按钮创建相同的功能 - On each click new button has been created. How should I create same functionality for new created buttons 将一个监听器添加到Promise之后,我应该使用原始的Promise还是新的Promise? - after adding a listener to a Promise, should I use the original promise or the new one? Javascript 中的扩展数组 Class:我应该如何创建辅助函数来修改数组而不分配新的引用? - Extended Array Class in Javascript: How should I create helper functions to modify Array without assigning a new reference? 我应该在 es6 中新建一个 utils 类吗? - Should I new a utils class in es6?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM