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

Con*_*Guy 4 javascript node.js promise async-await

我想在我的类方法中使用Promises.在Promise反模式中,我读到为每个新函数创建一个新的承诺被认为是坏的.

但是,我不想在我的项目中返回不相关的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);
      }
    )
  }

}
Run Code Online (Sandbox Code Playgroud)

然后我会像这样使用它:

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);

})();
Run Code Online (Sandbox Code Playgroud)

这看起来像是一种有效的方法吗,或者这也是一个反模式?如果是这样,我怎么能避免编写这样的代码?


编辑:如果我需要进行几个连续的http调用,对结果执行一些操作然后返回基于它的Promise怎么办?

我理解的方式,如果我不做一个新的 Promise,我必须返回got.js库创建的那个,其中包括http响应数据.

相反,我想返回一个包含我的类方法结果的Promise.

例:
  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

      }
    )
  }
Run Code Online (Sandbox Code Playgroud)

我不想返回包含got.js返回值的Promise ,我想根据http请求调用返回我的值.

Nik*_*des 6

async函数总是返回一个Promise.

在以下情况下,函数/方法将返回Promise:

  • 你明确地创建并从它的身体返回了一个Promise.
  • 您返回了一个存在于方法之外的Promise.
  • 你把它标记为async.

由于您可以await使用Promise并且instance.doSomething已经是异步标记的方法,因此您可以等待它而无需显式返回Promise.

简单地说,return它就像你在常规同步方法中那样.

我不想在我的项目中返回不相关的承诺......

除非您实际上在方法中执行异步操作(访问文件系统,数据库调用,计时器等...),否则无需将其包装在a中Promise,也不await需要在需要结果时将其包装.

实际需要在a中包装内容的最常见情况Promise是,如果你有一个使用回调工作的异步函数,但你想将它用作a 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)
})()
Run Code Online (Sandbox Code Playgroud)

我中省略的错误处理的简洁上面的代码片段,但你应该使用throwasync-marked方法引发错误.它相当于.reject()在Promise 中调用.