我想在我的课堂方法中利用Promises。在Promise antipatterns中,我读到为每个新函数创建一个新的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);
}
)
}
}
然后我会这样使用它:
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);
})();
这似乎是执行此操作的有效方法,还是这也是一种反模式?如果是这样,如何避免编写这样的代码?
编辑:如果我需要进行几个连续的http调用,对结果执行一些操作,然后基于该结果返回Promise,该怎么办?
根据我的理解,如果我不做一个 new 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
}
)
}
我不想返回包含 got.js 返回值的Promise,我想基于http请求调用返回 my 值。
答案 0 :(得分:6)
Promise
函数总是返回一个async
。
在以下情况下,函数/方法将返回Promise:
await
。由于您可以instance.doSomething
一个Promise,并且return
已经是一个异步标记的方法,因此您可以等待它而无需显式返回Promise。
简单地Promise
就像在常规同步方法中一样。
我不想在我的项目中返回无关的诺言...
除非您实际上在方法中执行异步操作(访问文件系统,数据库调用,计时器等...),否则不需要将其包装在{{1 }},也不需要await
。
实际上最需要将某些内容包装在Promise
中的情况是,如果您有一个使用callbacks起作用的异步函数,但又想将其用作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)
})()
为简洁起见,我在上面的代码段中省略了错误处理,但是您应该在标记为throw
的方法中使用async
来引发错误。这相当于在Promise中调用.reject()
。