gpt4 book ai didi

javascript - 异步函数永不返回

转载 作者:搜寻专家 更新时间:2023-10-31 23:32:26 24 4
gpt4 key购买 nike

我正在使用 Node 版本 7.6.0 来试用 native 异步和等待功能。

我想弄清楚为什么我的异步调用只是挂起而从未真正解决。

自然语言处理模块:

const rest = require('unirest')
const Redis = require('ioredis')
const redis = new Redis()
const Promise = require('bluebird')
const nlp = {}
nlp.queryCache = function(text) {
return new Promise(function(resolve, reject) {
redis.get(text, (err, result) => {
if (err) {
console.log("Error querying Redis: ", err)
reject(new Error("Error querying Redis: ", err))
} else {
if (result) {
let cache = JSON.parse(result)
console.log("Found cache in Redis: ", cache)
resolve(cache)
} else {
resolve(null)
}
}
})
})
}

nlp.queryService = function(text) {
console.log("Querying NLP Service...")
return new Promise(function(resolve, reject) {
rest.get('http://localhost:9119?q=' + text)
.end((response) => {
redis.set(text, JSON.stringify(text))
resolve(response.body)
})
})
}

nlp.query = async function(text) {
try {
console.log("LET'S TRY REDIS FIRST")
let cache = await nlp.queryCache(text)
if (cache) {
return cache
} else {
let result = await nlp.queryService(text)
console.log("Done Querying NLP service: ", result)
return result
}
} catch (e) {
console.log("Problem querying: ", e)
}

}
module.exports = nlp

模块消费者:

const modeMenu = require('../ui/service_mode')
const nlp = require('../nlp')
const sess = require('../session')
const onGreetings = async function(req, res, next) {
let state = sess.getState(req.from.id)
if (state === 'GREET') {
let log = {
middleware: "onGreetings"
}
console.log(log)
let result = await nlp.query(req.text)
console.log("XXXXXXXX: ", result)
res.send({reply_id: req.from.id, message: msg})

} else {
console.log("This query is not not normal text from user, calling next()")
next()
}
};
module.exports = onGreetings;

我无法获取继续执行以下行的代码:

console.log("XXXXXXXX: ", result) 

在NLP模块中可以看到查询成功

Console log output

Edit: Added console.log statement to response body

Console output on the actual response.body

Log statement

最佳答案

最可能的原因是您没有捕捉到 Promise 中的错误。我发现它有助于避免 try-catch 除了顶级调用方法之外的所有方法,如果一个方法可以被 await-ed 它几乎总是应该是。

在你的情况下,我认为问题出在这里:

nlp.queryService = function(text) {
console.log("Querying NLP Service...")
return new Promise(function(resolve, reject) {
rest.get('http://localhost:9119?q=' + text)
.end((response) => {
redis.set(text, JSON.stringify(text)) // this line is fire and forget
resolve(response.body)
})
})
}

特别是这一行:redis.set(text, JSON.stringify(text)) - 该行正在调用一个函数,没有发现任何错误。

解决方法是将所有 Redis 方法包装在 promises 中,然后始终 await 它们:

nlp.setCache = function(key, value) {
return new Promise(function(resolve, reject) {
redis.set(key, value, (err, result) => {
if (err) {
reject(new Error("Error saving to Redis: ", err));
} else {
resolve(result);
}
});
})
}

nlp.queryService = async function(text) {
console.log("Querying NLP Service...")
const p = new Promise(function(resolve, reject) {
rest.get('http://localhost:9119?q=' + text)
.end((response) => { resolve(response.body) });

// This is missing error handling - it should reject(new Error...
// for any connection errors or any non-20x response status
});

const result = await p;

// Now any issue saving to Redis will be passed to any try-catch
await nlp.setCache(text, result);
return;
}

作为一般规则,我发现最好的做法是:

  • 保持低级别的显式 promise - 为您的 restredis 回调提供 Promise 包装函数。
  • 确保您的 promise 在出现问题时reject并返回new Error。如果 Promise 没有resolve 也没有reject 那么你的代码就到此为止了。
  • 对这些 promise 包装器之一的每次调用都应该有 await
  • try-catch 就在顶部 - 只要每个 Promise 都是 await-ed 任何错误它们中的任何一个抛出的都将在顶层 catch
  • 中结束

大多数问题要么是:

  • 您有一个 Promise 可能无法resolvereject
  • 您在没有await 的情况下调用异步函数Promise

关于javascript - 异步函数永不返回,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42402750/

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