gpt4 book ai didi

javascript - 在 promise 中编写同步代码的正确方法是什么?

转载 作者:行者123 更新时间:2023-11-30 13:44:50 25 4
gpt4 key购买 nike

几天前,我在 YouTube 上看了一个关于 Broken Promises 的有趣视频。那James Snell介绍。

您可以从他的 repository 中找到视频中介绍的一些很好的示例.

According to what he said, we should not wrap purely synchronous code in a promise. And if we absolutely need a function to return a promise then resolve the promise synchronously by using Promise.resolve() method. Importantly, he also pointed out that run your code synchronously and save yourself the trouble of all those additional promise allocations.

看完视频后,我查看了我的代码。想知道如果我做了与他在剪辑中提到的类似的事情会怎样。

让我给你举几个例子。

这是一个等待 promise 被解析的异步函数。

async getGameShotDetail(buffer: Buffer, fileSize: number): Promise<ShotDetail[]> {
const { latitude, longitude, shotType } = await somefunc()
const data = await Promise.all([
this.parseHoleNumber(shotType),
this.parseShotType(shotType),
this.parseCoordinate(this.sliceBufferIntoPieces(latitude)),
this.parseCoordinate(this.sliceBufferIntoPieces(longitude)),
]);

return some async func(data);
}

Promise.all() 方法数组中的前两个方法 parseHoleNumberparseShotType 做几乎相同的事情。它从二进制文件中读取数据,它们最终都返回一个数字数组作为 promise 。

private parseHoleNumber(buffer: number[]): Promise<number[]> {
return new Promise((resolve, reject) => {
if (buffer.length < 0) {
reject([]);
}
/* tslint:disable:no-bitwise */
resolve(buffer.filter(n => n !== 0).map(holeNumber => holeNumber >> 3));
/* tslint:enable:no-bitwise */
});
}

我在这里试图完成的是编写返回 promise 的同步函数。问题是我不确定我的代码是否如 James Snell 所说的那样写得很好。

据我所知,所有Array包括推送在内的方法是同步的。而且我不确定从 new Promise(executor) 将项目推送到数组是否安全。

我的代码中是否存在任何易受攻击或错误使用的 promise ?

private sliceBufferIntoPieces(
buffer: number[] | string[],
chunkSize: number = 4,
): Promise<Array<number[]>> {
const arr = [];

return new Promise((resolve, reject) => {
for (let i = 0; i < buffer.length; i += chunkSize) {
arr.push(buffer.slice(i, i + chunkSize));
}
arr.length > 0 ? resolve(arr) : reject([]);
});
}

private async parseCoordinate(buffer: Promise<Array<number[]>>): Promise<number[]> {
const itemsAreZero = (item): boolean => item === 0;

return Promise.resolve(
(await buffer) // Maybe this is bad?
.filter(buff => !buff.every(itemsAreZero))
.map(byte => +(this.read4byteItem(byte) / 360000).toFixed(6)),
);
}

最佳答案

您代码中的所有函数都没有执行任何异步操作。一旦 await somefunc 行运行,您所做的其他所有事情都是同步的,但出于某种原因您仍然将所有内容包装在 Promise.all 调用中。您可以通过删除不必要的 Promise 构造和 Promise.resolves 来解决这个问题(并避免视频讨论的反模式):

async getGameShotDetail(buffer: Buffer, fileSize: number): Promise<ShotDetail[]> {
const { latitude, longitude, shotType } = await somefunc()
const data = [
this.parseHoleNumber(shotType),
this.parseShotType(shotType),
this.parseCoordinate(this.sliceBufferIntoPieces(latitude)),
this.parseCoordinate(this.sliceBufferIntoPieces(longitude)),
];

return some async func(data);
}
private parseHoleNumber(buffer: number[]): number[] {
if (buffer.length < 0) {
// If you don't want processing to continue in getGameShotDetail, throw an error:
throw new Error('Buffer length negative??');
// Otherwise, just return an empty array:
// return [];
}
/* tslint:disable:no-bitwise */
return buffer.filter(n => n !== 0).map(holeNumber => holeNumber >> 3);
/* tslint:enable:no-bitwise */
}
private sliceBufferIntoPieces(
buffer: number[] | string[],
chunkSize: number = 4,
): Array<number[]> {
const arr = [];

for (let i = 0; i < buffer.length; i += chunkSize) {
arr.push(buffer.slice(i, i + chunkSize));
}
if (arr.length === 0) {
// Same as above - do you want to return an empty array, or stop execution entirely?
throw new Error('Buffer empty');
}
}

关于上面的两个函数,如果缓冲区是空的,考虑一下——你真的想完全停止执行,还是想用一个空数组继续执行?如果你想停止执行,抛出一个错误(使用 throw)——否则,不抛出,只返回一个空数组。

因为 sliceBufferIntoPieces 不需要返回 Promise,所以 parseCoordinate 也不需要等待它解决:

private parseCoordinate(buffer: Array<number[]>): number[] {
const itemsAreZero = (item): boolean => item === 0;

return buffer
.filter(buff => !buff.every(itemsAreZero))
.map(byte => +(this.read4byteItem(byte) / 360000).toFixed(6))
}

另请记住,Typescript 几乎总是可以推断出函数返回值的类型,而无需您明确指定它 - 除非您的 linter 强制您注意返回类型,否则请随意将其省略。

关于javascript - 在 promise 中编写同步代码的正确方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59526342/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com