Next.JS:带有 promise 的解析器在 SSR 上的 api-routes-server-and-client-test 中不起作用
Next.JS: Resolver with promise doesn't work in api-routes-server-and-client-test on SSR
使用 next.js 示例 api-routes-apollo-server-and-client。当我尝试以这种方式在 apollo/resolvers.js
中实施延迟时:
export const resolvers = {
Query: {
viewer (_parent, _args, _context, _info) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve({ id: 1, name: 'John Smith', status: 'cached' });
}, 1000);
})
}
}
}
这在 SSR 中不起作用。 SSR apollo 状态下数据为空,但需要用户数据 { id: 1, name: 'John Smith', status: 'cached' }
.
我也在使用它和 sequelize 从数据库中获取数据,但它也不起作用。我想原因是一样的。
也许我做错了什么。
客户端部分正常(React水合后显示数据)
如果我们使用静态对象而不是 Promise:
export const resolvers = {
Query: {
viewer (_parent, _args, _context, _info) {
return { id: 1, name: 'John Smith', status: 'cached' };
}
}
}
一切正常,这会将对象置于从具有正确静态标记的 SSR 服务器返回的初始状态...
我在期待什么?
我只想要服务器呈现 graphql 请求,完成承诺,将数据放入 apollo 状态以用于 SSR,并为 SEO 目的执行 SSR。因为现在如果我连接到数据库 - 它根本不起作用(什么都没有呈现。只是空页面,因为呈现被某些东西打断了)。
如果您正在尝试模拟解决远程请求或解决一般处理程序中的承诺所涉及的可能延迟,请尝试以下操作:
export const resolvers = {
Query: {
async viewer(_parent, _args, _context, _info) {
try {
const resp = await new Promise((resolve, reject) => {
setTimeout(() => {
resolve({ id: 1, name: 'John Smith', status: 'cached' })
}, 1000)
})
return resp
} catch (err) {
throw new Error('failed')
}
// return { id: 1, name: 'John Smith', status: 'cached' }
},
},
}
return await new Promise()
不起作用,因为 await 关键字在那种情况下不做任何事情,对象 returned 是 still 一个承诺,您的解析器期望 return 值是一个对象。
将 await new Promise(...)
分配给变量可确保承诺已解决,并且变量在 returned 之前包含预期的对象。
您的代码完全正确,SSR 没有问题。我在 CSR 和 SSR 模式下使用 next.js 示例 api-routes-apollo-server-and-client 测试了您的代码。 SSR测试先运行npm run build
然后npm start
。如果您的问题没有解决,请尝试更新 node.js 并重新下载示例代码并再次测试它。
使用 next.js 示例 api-routes-apollo-server-and-client。当我尝试以这种方式在 apollo/resolvers.js
中实施延迟时:
export const resolvers = {
Query: {
viewer (_parent, _args, _context, _info) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve({ id: 1, name: 'John Smith', status: 'cached' });
}, 1000);
})
}
}
}
这在 SSR 中不起作用。 SSR apollo 状态下数据为空,但需要用户数据 { id: 1, name: 'John Smith', status: 'cached' }
.
我也在使用它和 sequelize 从数据库中获取数据,但它也不起作用。我想原因是一样的。
也许我做错了什么。
客户端部分正常(React水合后显示数据)
如果我们使用静态对象而不是 Promise:
export const resolvers = {
Query: {
viewer (_parent, _args, _context, _info) {
return { id: 1, name: 'John Smith', status: 'cached' };
}
}
}
一切正常,这会将对象置于从具有正确静态标记的 SSR 服务器返回的初始状态...
我在期待什么?
我只想要服务器呈现 graphql 请求,完成承诺,将数据放入 apollo 状态以用于 SSR,并为 SEO 目的执行 SSR。因为现在如果我连接到数据库 - 它根本不起作用(什么都没有呈现。只是空页面,因为呈现被某些东西打断了)。
如果您正在尝试模拟解决远程请求或解决一般处理程序中的承诺所涉及的可能延迟,请尝试以下操作:
export const resolvers = {
Query: {
async viewer(_parent, _args, _context, _info) {
try {
const resp = await new Promise((resolve, reject) => {
setTimeout(() => {
resolve({ id: 1, name: 'John Smith', status: 'cached' })
}, 1000)
})
return resp
} catch (err) {
throw new Error('failed')
}
// return { id: 1, name: 'John Smith', status: 'cached' }
},
},
}
return await new Promise()
不起作用,因为 await 关键字在那种情况下不做任何事情,对象 returned 是 still 一个承诺,您的解析器期望 return 值是一个对象。
将 await new Promise(...)
分配给变量可确保承诺已解决,并且变量在 returned 之前包含预期的对象。
您的代码完全正确,SSR 没有问题。我在 CSR 和 SSR 模式下使用 next.js 示例 api-routes-apollo-server-and-client 测试了您的代码。 SSR测试先运行npm run build
然后npm start
。如果您的问题没有解决,请尝试更新 node.js 并重新下载示例代码并再次测试它。