如何等到回调被调用
Posted
技术标签:
【中文标题】如何等到回调被调用【英文标题】:How to wait until callback is called 【发布时间】:2019-05-22 20:59:59 【问题描述】:我有一个执行长时间计算的函数,一旦完成,就会调用一个作为参数传递的回调函数。
我在 Koa 路由器中查询这个函数,需要将长时间计算的结果返回给浏览器。函数来自库,我无法更改其接口(即,我可以更改回调的代码,但无法更改 someLongComputation
以返回承诺)
当前代码集ctx.body
立即返回,someLongComputation
立即返回。知道,然后才使用回调的结果设置ctx.body
。
router.post(`/abc`, async (ctx) =>
try
someLongComputation(function(err, res)
if(err)
console.log(err);
ctx.body =
status: 'success',
data: 'res' : "",
errors: []
;
catch (err)
console.log(err)
)
【问题讨论】:
是的,您可以更改someLongComputation()
以使用承诺:require('util').promisify(someLongComputation)
返回您可以使用 await
的函数版本。
为简单起见,我省略了 someLongComputation 函数的实际名称。我正在尝试使用在调整大小后运行的 graphicsmagic 流函数来做到这一点: gm(request(photo)).resize(size[0], size[1]).stream 。在该代码上使用 promisify 似乎会返回错误:TypeError: format.split is not a function
【参考方案1】:
你有两个选择。
1。从您的回调中发送响应
router.post(`/abc`, async (ctx) =>
try
someLongComputation(function(err, res)
if (err)
console.log(err);
// you might want to send error response here
// send response from callback
ctx.body =
status: 'success',
data: res: '' ,
errors: []
;
);
catch (err)
console.log(err);
// you might want to send error response here as well
);
2。从您的库函数中创建一个承诺并使用async/await
const doLongComputation = () =>
return new Promise((resolve, reject) =>
try
someLongComputation(function(err, res)
if (err)
console.log(err);
reject(err);
resolve(res);
);
catch (err)
console.log(err);
reject(err);
);
;
router.post(`/abc`, async (ctx) =>
try
const res = await doLongComputation();
ctx.body =
status: 'success',
data: res: '' ,
errors: []
;
catch (err)
console.log(err);
// send error response here
);
【讨论】:
【参考方案2】:如果您想使用 async/await 并假设 longcomputation 函数可以返回一个 Promise,您可以更改您的代码以等待该函数的返回。
router.post(`/abc`, async (ctx) =>
try
const result = await someLongComputation();
// do whatever you want with result
catch (err)
console.log(err)
)
另一种选择是在函数的回调中使用变量
router.post(`/abc`, async (ctx) =>
try
someLongComputation(function(err, res)
if(err)
console.log(err);
//moved setting the body to inside the callback for the computation
ctx.body =
status: 'success',
data: 'res' : "",
errors: []
;
catch (err)
console.log(err)
)
【讨论】:
谢谢彼得的回答。您的第一个解决方案将不起作用,因为我无法更改功能。我已经更新了我的问题以明确说明它的库函数。我刚刚测试了第二种解决方案,代码立即返回 404。 @user1217406 你是说你无法修改提供给someLongComputation()
的匿名回调函数?总的来说,我很难弄清楚你认为什么是你可以修改的代码和你不能修改的代码
进一步编辑了问题。我可以更改回调,但我无法更改 someLongComputation
以使用承诺或以任何其他方式更改其接口。
如果您在回调中设置响应,我不确定为什么它会返回 404。另一个选项在下面的答案中。将您长期运行的函数包装在一个返回承诺然后等待该结果的函数中。我不知道引用另一个人的答案的礼仪是什么,但遵循@DaneshPandiyan 概述的答案应该会有所帮助以上是关于如何等到回调被调用的主要内容,如果未能解决你的问题,请参考以下文章