Promise 保持待定状态,Returns Null
Promise Stays Pending, Returns Null
我正在处理一个 GraphQL 查询,我试图在其中找到一个独特的模型。但是,没有任何东西得到 returned,因为代码在查询完成之前一直在继续,因此在它期望模型时尝试 return Promise。代码如下所示...
const findShift = async (date) => {
console.log("In mutation function")
const foundShift = await db.shift.findUnique({
where: {
date: date
}
})
return foundShift
}
const foundShift = findShift(date).then( resolved => {
console.log("printing resolved...")
console.log(resolved)
if (resolved.id != 'undefined'){
console.log({
id: resolved.id,
date: resolved.date,
allDevices: resolved.allDevices
})
return foundShift
}
else{
throw new Error("no shift of that date found!")
}
})
console.log 语句使控制台看起来如此...
In mutation function
Promise { <pending> }
prisma:info Starting a postgresql pool with 9 connections.
最终查询只是 returns null
。如您所见,我尝试使用 then
并将突变本身放入一个完全不同的函数中,只是为了规避这些异步问题,但无济于事。有人看到解决方法吗?
首先,所有 async
函数 return 一个承诺。异步函数中的 return 值成为该承诺的解析值。因此,async
函数的调用者必须使用 .then()
或 await 从异步函数中获取解析值。没有办法像您尝试的那样“规避”异步性。你可以驯服它使它更有用,但你无法逃避它。因此,您的 async
函数 return 是一个悬而未决的承诺,它最终将解析为您 return 在 async
函数中的任何值。
您可以在另一个答案中阅读有关 async
函数如何工作的更多信息 。
在尝试对您的代码进行 minimal, reproducible example 时,我将其简化为我用异步模拟代替数据库调用的地方:
function delay(t, v) {
return new Promise(resolve => setTimeout(resolve, t, v));
}
// simulate asynchronous database operation
const db = {
shift: {
findUnique: function(data) {
return delay(100, { id: 123, date: Date.now(), allDevices: ["iPhone", "Galaxy", "Razr"] });
}
}
}
const findShift = async (date) => {
console.log("In mutation function")
const found = await db.shift.findUnique({
where: {
date: date
}
})
return found;
}
const date = Date.now();
const foundShift = findShift(date).then(resolved => {
console.log("printing resolved...")
console.log(resolved);
if (resolved.id != 'undefined') {
console.log({
id: resolved.id,
date: resolved.date,
allDevices: resolved.allDevices
})
return foundShift
} else {
throw new Error("no shift of that date found!")
}
});
当我在 nodejs 中 运行 时,我得到这个错误:
[TypeError: Chaining cycle detected for promise #<Promise>]
而且,错误是由这行代码引起的:
return foundShift
您正试图从承诺链中 return 已经是该承诺链一部分的承诺。这会产生不允许的循环依赖。
您需要什么 return 您希望父承诺的解析值是什么。因为它看起来像是您在其上方构造的对象,所以我修改了代码来执行此操作。此代码可以是 运行 并且 foundShift
是解析为您的对象的承诺。
function delay(t, v) {
return new Promise(resolve => setTimeout(resolve, t, v));
}
// simulate asynchronous database operation
const db = {
shift: {
findUnique: function(data) {
return delay(100, { id: 123, date: Date.now(), allDevices: ["iPhone", "Galaxy", "Razr"] });
}
}
}
const findShift = async (date) => {
const found = await db.shift.findUnique({
where: {
date: date
}
})
return found;
}
const date = Date.now();
const foundShift = findShift(date).then(resolved => {
if (resolved.id != 'undefined') {
let result = {
id: resolved.id,
date: resolved.date,
allDevices: resolved.allDevices
};
return result;
} else {
throw new Error("no shift of that date found!")
}
});
// foundShift here is a promise
// to get it's value, you have to use .then() or await on it
foundShift.then(result => {
console.log("final result", result);
}).catch(e => {
console.log(e);
});
这里有一些关于承诺的规则可能会有所帮助:
- 所有
fn().then()
或 fn().catch()
调用 return 一个链接到 fn()
returned 的新承诺。
- 所有
async
功能 return 承诺。
- 您不能“规避”异步性并以某种方式直接return 异步检索的值。您必须使用回调、事件或 return 承诺(或某种类似的异步机制)才能将异步检索的值传回给调用者。
await
只能在 async
函数内部使用(或在 ESM 模块的顶层)。
- 函数中的第一个
await
暂停 async
函数的执行,然后立即 return 向调用者发出未实现的承诺。所以,await
只影响当前函数的流程,而不影响调用者的流程。调用者仍然必须使用 .then()
或 await
来从 async
函数 returns. 的承诺中获取值
- 尽可能尝试,没有办法绕过这些规则(在 Javascript 中,因为它目前在浏览器或 nodejs 中 运行)。
我正在处理一个 GraphQL 查询,我试图在其中找到一个独特的模型。但是,没有任何东西得到 returned,因为代码在查询完成之前一直在继续,因此在它期望模型时尝试 return Promise。代码如下所示...
const findShift = async (date) => {
console.log("In mutation function")
const foundShift = await db.shift.findUnique({
where: {
date: date
}
})
return foundShift
}
const foundShift = findShift(date).then( resolved => {
console.log("printing resolved...")
console.log(resolved)
if (resolved.id != 'undefined'){
console.log({
id: resolved.id,
date: resolved.date,
allDevices: resolved.allDevices
})
return foundShift
}
else{
throw new Error("no shift of that date found!")
}
})
console.log 语句使控制台看起来如此...
In mutation function
Promise { <pending> }
prisma:info Starting a postgresql pool with 9 connections.
最终查询只是 returns null
。如您所见,我尝试使用 then
并将突变本身放入一个完全不同的函数中,只是为了规避这些异步问题,但无济于事。有人看到解决方法吗?
首先,所有 async
函数 return 一个承诺。异步函数中的 return 值成为该承诺的解析值。因此,async
函数的调用者必须使用 .then()
或 await 从异步函数中获取解析值。没有办法像您尝试的那样“规避”异步性。你可以驯服它使它更有用,但你无法逃避它。因此,您的 async
函数 return 是一个悬而未决的承诺,它最终将解析为您 return 在 async
函数中的任何值。
您可以在另一个答案中阅读有关 async
函数如何工作的更多信息
在尝试对您的代码进行 minimal, reproducible example 时,我将其简化为我用异步模拟代替数据库调用的地方:
function delay(t, v) {
return new Promise(resolve => setTimeout(resolve, t, v));
}
// simulate asynchronous database operation
const db = {
shift: {
findUnique: function(data) {
return delay(100, { id: 123, date: Date.now(), allDevices: ["iPhone", "Galaxy", "Razr"] });
}
}
}
const findShift = async (date) => {
console.log("In mutation function")
const found = await db.shift.findUnique({
where: {
date: date
}
})
return found;
}
const date = Date.now();
const foundShift = findShift(date).then(resolved => {
console.log("printing resolved...")
console.log(resolved);
if (resolved.id != 'undefined') {
console.log({
id: resolved.id,
date: resolved.date,
allDevices: resolved.allDevices
})
return foundShift
} else {
throw new Error("no shift of that date found!")
}
});
当我在 nodejs 中 运行 时,我得到这个错误:
[TypeError: Chaining cycle detected for promise #<Promise>]
而且,错误是由这行代码引起的:
return foundShift
您正试图从承诺链中 return 已经是该承诺链一部分的承诺。这会产生不允许的循环依赖。
您需要什么 return 您希望父承诺的解析值是什么。因为它看起来像是您在其上方构造的对象,所以我修改了代码来执行此操作。此代码可以是 运行 并且 foundShift
是解析为您的对象的承诺。
function delay(t, v) {
return new Promise(resolve => setTimeout(resolve, t, v));
}
// simulate asynchronous database operation
const db = {
shift: {
findUnique: function(data) {
return delay(100, { id: 123, date: Date.now(), allDevices: ["iPhone", "Galaxy", "Razr"] });
}
}
}
const findShift = async (date) => {
const found = await db.shift.findUnique({
where: {
date: date
}
})
return found;
}
const date = Date.now();
const foundShift = findShift(date).then(resolved => {
if (resolved.id != 'undefined') {
let result = {
id: resolved.id,
date: resolved.date,
allDevices: resolved.allDevices
};
return result;
} else {
throw new Error("no shift of that date found!")
}
});
// foundShift here is a promise
// to get it's value, you have to use .then() or await on it
foundShift.then(result => {
console.log("final result", result);
}).catch(e => {
console.log(e);
});
这里有一些关于承诺的规则可能会有所帮助:
- 所有
fn().then()
或fn().catch()
调用 return 一个链接到fn()
returned 的新承诺。 - 所有
async
功能 return 承诺。 - 您不能“规避”异步性并以某种方式直接return 异步检索的值。您必须使用回调、事件或 return 承诺(或某种类似的异步机制)才能将异步检索的值传回给调用者。
await
只能在async
函数内部使用(或在 ESM 模块的顶层)。- 函数中的第一个
await
暂停async
函数的执行,然后立即 return 向调用者发出未实现的承诺。所以,await
只影响当前函数的流程,而不影响调用者的流程。调用者仍然必须使用.then()
或await
来从async
函数 returns. 的承诺中获取值
- 尽可能尝试,没有办法绕过这些规则(在 Javascript 中,因为它目前在浏览器或 nodejs 中 运行)。