gpt4 book ai didi

javascript - 有没有办法将回调函数转换为 TypeScript/JavaScript 中的生成器?

转载 作者:行者123 更新时间:2023-11-30 19:10:07 25 4
gpt4 key购买 nike

我正在使用 Axios 调用具有进度指示器的 api 端点。我想将 onUploadProgress 转换为生成器。

有没有办法转换这段代码

setProgress({ state: 'syncing', progress: 0 });

await axios.post(uri.serialize(parsedURI), body2, {
headers: { session_id: sessionId },
onUploadProgress: (progress) => {
setProgress({ state: 'syncing', progress: progress.loaded / progress.total });
},
});
setProgress({ state: 'syncing', progress: 1 });

变成这样

yield { state: 'syncing', progress: 0 };

await axios.post(uri.serialize(parsedURI), body2, {
headers: { session_id: sessionId },
onUploadProgress: (progress) => {
yield { state: 'syncing', progress: progress.loaded / progress.total };
},
});
yield { state: 'syncing', progress: 1 };

问题出在 onUploadProgress 中的 yield,我在想可能有一种方法可以使用它,就像您想要将回调转换为您使用的 promise 一样

new Promise(resolve => fn(resolve));

对于像这样的生成器,也许有一些有效的方法可以做到这一点

new Generator(next => fn(next));

最佳答案

您可以更新进度处理程序中的局部变量并在循环中轮询它直到请求完成。这是一个草图:

let delay = n => new Promise(res => setTimeout(res, n));


async function request(n, onProgress) {
for (let i = 0; i < n; i++) {
onProgress(i);
await delay(200);
}
return 'response'
}


async function* requestWithProgress(result) {
let prog = 0,
prevProg = 0,
res = null;

let req = request(10, n => prog = n)
.then(r => res = r);

while (!res) {
await delay(1);
if (prog > prevProg)
yield prevProg = prog;
}

result.res = res;
}


async function main() {
let result = {}
for await (let prog of requestWithProgress(result))
console.log(prog)
console.log(result)
}


main()

这是另一种选择,没有轮询,并且返回 API 更好:

function progressiveAsync(factory) {
let
resultPromise = null,
resultResolver = null,
genPromise = null,
genResolver = null,
stop = {};

resultPromise = new Promise(r => resultResolver = r);
genPromise = new Promise(r => genResolver = r);

async function* gen() {
while (true) {
let r = await genPromise;
if (r === stop) {
break;
}
yield r;
}
}

factory(
val => {
genResolver(val);
genPromise = new Promise(r => genResolver = r);
},
val => {
genResolver(stop);
resultResolver(val);
}
);

return [gen(), resultPromise];
}

//


async function testRequest(opts /* count, onProgress */) {
return new Promise(async res => {
for (let i = 0; i < opts.count; i++) {
opts.onProgress(i);
await new Promise(resolve => setTimeout(resolve, 300));
}
res('response!')
})
}


async function main() {
let [progress, result] = progressiveAsync((next, done) =>
testRequest({
count: 10,
onProgress: next
}).then(done));

for await (let n of progress)
console.log('progress', n)

console.log(await result)
}

main()

关于javascript - 有没有办法将回调函数转换为 TypeScript/JavaScript 中的生成器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58578636/

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