不链接异步功能?
在尝试为朋友重新编码旧系统时,我遇到了与使用Jimp节点包进行异步函数调用的一些问题:
这是我放在一起的代码:
async format(file, config = {}) {
try {
return Jimp.read(file).then(image => {
if (config.quality) {
const quality = parseInt(config.quality.replace(/\D+/g, ''), 10);
image.quality(quality);
}
if (config.brightness) {
image.brightness(config.brightness);
}
return image.getBufferAsync(Jimp.MIME_JPEG);
}).catch(error => {
console.error(error);
});
} catch (err) {
console.log(err);
return false;
}
}
let response = await this.format(file.Body, config);
这是我放在一起的极简主义版本,但我不确定为什么输出缓冲区为0kb?我在想它是因为我没有把每个功能都当作承诺?
回答如下:你正在写一个async
函数,但你没有使用await
- 这使得使用async
使Promises更容易使用的观点失败了。
试试这个:
async format( file, config = {} ) {
let image = await Jimp.read( file );
if( config.quality ) {
const quality = parseInt(config.quality.replace(/\D+/g, ''), 10);
image.quality(quality);
}
if( config.brightness ) {
image.brightness(config.brightness);
}
let buffer = await image.getBufferAsync( Jimp.MIME_JPEG );
return buffer;
}
JavaScript中的async
和await
关键字与其C#关键字的行为基本相同(除了在Promise<T>
而不是Task<T>
上运行)。 await
关键字只能在具有async
修饰符的函数中使用(它还意味着所有async
函数也必然返回Promise<T>
)。
所以这:
async foo() { // returns Promise<T>
let a = getA();
let b = await getBAsync( a );
let c = getC( b );
let d = await getDAsync( c );
return d;
}
相当于:
foo() { // returns Promise<T>
let a = getA();
let bPromise = getBAsync( a );
return bPromise.then( b => {
let c = getC( b );
let dPromise = getDAsync( c );
return dPromise.then( d => {
return d;
} );
} );
}
或者(使用Promise链接):
foo() { // returns Promise<T>
let a = getA();
return getBAsync( a )
.then( b => {
let c = getC( b );
return c;
} )
.then( c => {
return getDAsync( c );
} );;
}
提示:
- 在我看来,你应该更喜欢使用TypeScript到JavaScript,因为如果你依赖JavaScript的弱类型,正确使用
Promise<T>
会遇到困难。 - 如果你不能使用TypeScript,你仍然可以使用
*.d.ts
文件作为参考,这样你就知道你正在使用哪些库函数返回Promise<T>
(异步函数)并返回T
(同步,“普通”函数) 例如,Jimp的d.ts
文件可在此处获取:https://github/oliver-moran/jimp/blob/master/packages/jimp/jimp.d.ts - 一个常见的编码约定是使用
Async
后缀函数名称,如果它返回Promise<T>
作为礼貌给你的任何库消费者(虽然这不是普遍常见的,例如ESLint决定反对它:https://github/eslint/eslint/issues/8531)
不链接异步功能?
在尝试为朋友重新编码旧系统时,我遇到了与使用Jimp节点包进行异步函数调用的一些问题:
这是我放在一起的代码:
async format(file, config = {}) {
try {
return Jimp.read(file).then(image => {
if (config.quality) {
const quality = parseInt(config.quality.replace(/\D+/g, ''), 10);
image.quality(quality);
}
if (config.brightness) {
image.brightness(config.brightness);
}
return image.getBufferAsync(Jimp.MIME_JPEG);
}).catch(error => {
console.error(error);
});
} catch (err) {
console.log(err);
return false;
}
}
let response = await this.format(file.Body, config);
这是我放在一起的极简主义版本,但我不确定为什么输出缓冲区为0kb?我在想它是因为我没有把每个功能都当作承诺?
回答如下:你正在写一个async
函数,但你没有使用await
- 这使得使用async
使Promises更容易使用的观点失败了。
试试这个:
async format( file, config = {} ) {
let image = await Jimp.read( file );
if( config.quality ) {
const quality = parseInt(config.quality.replace(/\D+/g, ''), 10);
image.quality(quality);
}
if( config.brightness ) {
image.brightness(config.brightness);
}
let buffer = await image.getBufferAsync( Jimp.MIME_JPEG );
return buffer;
}
JavaScript中的async
和await
关键字与其C#关键字的行为基本相同(除了在Promise<T>
而不是Task<T>
上运行)。 await
关键字只能在具有async
修饰符的函数中使用(它还意味着所有async
函数也必然返回Promise<T>
)。
所以这:
async foo() { // returns Promise<T>
let a = getA();
let b = await getBAsync( a );
let c = getC( b );
let d = await getDAsync( c );
return d;
}
相当于:
foo() { // returns Promise<T>
let a = getA();
let bPromise = getBAsync( a );
return bPromise.then( b => {
let c = getC( b );
let dPromise = getDAsync( c );
return dPromise.then( d => {
return d;
} );
} );
}
或者(使用Promise链接):
foo() { // returns Promise<T>
let a = getA();
return getBAsync( a )
.then( b => {
let c = getC( b );
return c;
} )
.then( c => {
return getDAsync( c );
} );;
}
提示:
- 在我看来,你应该更喜欢使用TypeScript到JavaScript,因为如果你依赖JavaScript的弱类型,正确使用
Promise<T>
会遇到困难。 - 如果你不能使用TypeScript,你仍然可以使用
*.d.ts
文件作为参考,这样你就知道你正在使用哪些库函数返回Promise<T>
(异步函数)并返回T
(同步,“普通”函数) 例如,Jimp的d.ts
文件可在此处获取:https://github/oliver-moran/jimp/blob/master/packages/jimp/jimp.d.ts - 一个常见的编码约定是使用
Async
后缀函数名称,如果它返回Promise<T>
作为礼貌给你的任何库消费者(虽然这不是普遍常见的,例如ESLint决定反对它:https://github/eslint/eslint/issues/8531)