Having a issue where Koa is returning early and not waiting for any of my await functions to finish.
Node: 9.10
//root.js
module.exports = async (ctx, next) => {
const test = new Promise(function(resolve, reject) {
setTimeout(() => {
return resolve('word');
}, 1000);
});
ctx.body = await test
}
//index.js
app.use(async ctx => {
switch(ctx.path) {
case '/':
await root(ctx);
break;
}
})
This always throws a 404. How can I get Koa to wait for the await function to finish?
Figured it out, I need to be returning the middle into Koa itself and check the route in module itself because of the way i set it up. Sorry to bother.
Ran into another similar issue with await Promise.all
//root.js
let feedPromises = feeds.map(feed => {
return new Promise(function(resolve, reject) {
setTimeout(() => {
return resolve('word');
}, 1000);
});
});
let result;
try {
result = await Promise.all(feedPromises) // after this line koa returns
} catch(e) {
console.log(e);
}
ctx.body = result; // this is happening after the return
I'm going to to need a full example of what you're doing to pinpoint any issue. There's insufficient information for me to be helpful here. On a different note, general usage questions are better suited elsewhere and you might get help faster - unless you think this is a Koa bug in which case I'd ask you to provide a fully reproducible example for further investigation.
Sorry, provided a full example. I'm not sure if its a bug, the behavior doesn't seem like its inline with how the docs describe the behavior but I can definetly be wrong. Koa version 2.5.1
//index.js
const Koa = require('koa');
const app = new Koa();
const update = require('./routes/index.js');
app.use(index);
app.listen(3000, () => { console.log('listening on 3000') });
// routes/index.js
module.exports = async (ctx, next) => {
let promise = () => {
return new Promise(function(resolve, reject) {
setTimeout(() => {
return resolve('word');
}, 10);
});
}
result = await Promise.all([promise()])
// result = await promise() //this and the above line are happening after koa has already returned
ctx.body = result;
}
The only thing I see is that you're assigning to result without defining it. In strict mode this causes a ReferenceError, not sure how it plays out in normal mode. Anyway, I can't recreate your issue because I'm getting expected results (i.e. word).
You require routes/index.js as update, but you app.use it as index.
Ended up figuring it out. I was testing this code inside of a larger koa application. And in one of the other middleware files, I was not using await next(), when I updated my code everything worked properly. My bad.
Hello , I have similar issue :
app.use(async (ctx, next) => {
const req = ctx.req.req || ctx.req;
ctx.mySelf = await new Promise((resolve, reject) => {
// req.on('data', (buffer) => {
// const value = buffer.toString('utf-8')
// resolve(JSON.parse(value))
// })
setTimeout(() => {
resolve('test')
}, 1000)
})
console.log(ctx.mySelf)
await next()
})
app.use(bodyParser());
It works , but If run the annotated code, the http request is always pending.
The console also has no output
interview.js
const interviewRouter = require('./routes/interview');
app.use(router.routes()).use(router.allowedMethods());
router.use('/interview', interviewRouter.routes(), interviewRouter.allowedMethods());
interviewRouter.post('/post', async (ctx) => {
console.log(ctx.request.body)
console.log(ctx.mySelf)
ctx.body = {
success: true
}
})
Ohh. My fault... It doesn't matter of koa.
Hello guys,
How can i use await Promise.all for my function?
i have use kao v2.7 and when i call await Promise.all as my function it's return 404 every time how i can fix it... please help
Thanks.
@Cmdrobot you probably just missed to return. Remember that Promise.all also is a promise.
@Cmdrobot , you can simplify your code, and show it. It's better way for get answer.
async function generateVideoThumb(videoPath, savePath, imageSize) {
return new Promise((resolve, reject) => {
ffmpeg(videoPath).on('error', (err) => {
reject(err);
console.log('err:', err)
}).on('end', function(){
resolve()
console.log('success')
}).screenshots({
timestamps: ['25%', '50%', '75%'],
filename: `%b.jpg`,
folder: `public/uploads/${savePath}/thumbnails`,
size: `${imageSize.width}x${imageSize.height}`,
count: 1
});
});
}
var upload = async function(ctx, next){
const results = files.map(async file => {
let filenames = file.name.split(".")
let ext = filenames.length > 1 ? filenames[filenames.length - 1]:"jpg"
var savePath = "files"
if (file.type == "image/jpg" || file.type == "image/jpeg" || file.type == "image/png") {
savePath = "images"
}else if (file.type == "video/mp4" || file.type == "video/quicktime") {
savePath = "videos"
}
let name = Math.random().toString().replace(".", "")
let filename = `files-${name}.${ext}`
let filePath = `./public/uploads/${savePath}/`+filename
var imageSize = {width: 0, height: 0}
if (file.type == "image/jpg" || file.type == "image/jpeg" || file.type == "image/png") {
imageSize = await imageSizeWithPath(savePath, filename)
}else if (file.type.match("video")){
imageSize = {width: 320, height: 240}
let videoPath = `public/uploads/${savePath}/${filename}`;
await generateVideoThumb(videoPath, savePath, imageSize)
}
return {
"content-type": file.type,
"url": "??????",
"width": imageSize.width || 0,
"height": imageSize.height || 0
}
})
let output = await Promise.all(results) <----- this line is fine when i have log as console
// after this line i have receive response code is 404
ctx.status = 200;
ctx.body = ctx.config.response(200, 'test', output)
await next();
})
please help......thanks
router.get(`${BASE_URL}/testAsync`, async (ctx) => {
ctx.response.body = await f1()
});
async function f1() {
return new Promise((resolve, reject) => {
let message = {
greeting: "Hello",
planet: "World"
}
setInterval(function(){
resolve(message)
}, 3000);
})
}
And this function is same issue
This code works very well, and don't know what your question. @Cmdrobot
var app = new Koa();
var router = new Router();
function f1() { // no need use async in here, async and await use by pairs
return new Promise((resolve, reject) => {
let message = {
greeting: "Hello",
planet: "World"
}
setTimeout(function(){ // why use setInterval?
resolve(message)
}, 3000);
})
}
router.get('/test-async', async (ctx) => {
ctx.response.body = await f1();
});
app
.use(router.routes())
.use(router.allowedMethods());
app.listen(3000);
Ended up figuring it out. I was testing this code inside of a larger koa application. And in one of the other middleware files, I was not using
await next(), when I updated my code everything worked properly. My bad.
I spent many hours finding the issue and this made it clear ! thanks a lot @fedgrant
Ended up figuring it out. I was testing this code inside of a larger koa application. And in one of the other middleware files, I was not using
await next(), when I updated my code everything worked properly. My bad.
You saved me, man. Thanks a lot @fedgrant
Most helpful comment
Ended up figuring it out. I was testing this code inside of a larger koa application. And in one of the other middleware files, I was not using
await next(), when I updated my code everything worked properly. My bad.