为什么 nexus dev 命令运行应用程序两次,如何解决?
Why nexus dev command runs app twice, and how to fix it?
我使用 nexus graphql 框架创建了超级简单的应用程序。
第一步是这样的:
https://www.nexusjs.org/#/tutorial/chapter-1-setup-and-first-query
我api/app.ts
我输入了代码:
const uid = require('uid')
let i = 0;
const sleep = async (ms: number) => {
return new Promise((resolve, reject) => {
setTimeout(resolve, ms)
})
}
const recurrenceFunction = async (id:string): Promise<void> => {
i++;
console.log(id, i);
await sleep(2000);
return recurrenceFunction(id)
}
const startQueue = () => {
const id:string = uid();
return recurrenceFunction(id)
}
(async () => {
return startQueue()
})()
唯一的依赖项是生成唯一键的 uid
。
当我 运行 它与 ts-node 我可以看到:
所以我们可以看到:
- 一旦队列开始。
- 只有一个队列。
- 它正常工作。
但是当我 运行 通过命令 nexus
使用 nexus
这段代码时 nexus dev
我看到了:
所以:
- 两个队列已启动。
- 他们同时运行宁。
- 他们已经独立创建了变量
i
。
问题:
- 有人遇到过这个问题吗?
- 我应该如何更改我的代码以获得像
ts-node
中那样的单队列?
- 或者可能是
nexus
的错误?
更新:
我检查过 >= 0.21.1-next.2
的版本是否存在这个问题
在0.21.1-next.1
应用运行s单次。
重现步骤:
nexus dev
npm i nexus@0.21.1-next.1
nexus dev
npm i nexus@0.21.1-next.2
有引入此行为的提交:
https://github.com/graphql-nexus/nexus/commit/ce1d45359e33af81169b7ebdc7bee6718fe313a8
有 onMainThread
和 REFLECTION_ENV_VAR
之类的变量,但没有对文档的引用。我不明白这段代码在做什么?
这可能会在未来记录在这个地方:
https://www.nexusjs.org/#/architecture?id=build-flow
但现在有:
更新 2
我找到了解决方法:
const xid = uid();
let limit=10;
const onApplicationStart = async (cb: () => any):Promise<any> => {
console.log("can i start?", xid, limit, app.private.state.running);
if(app.private.state.running) {
await cb()
return;
}
limit--;
if(limit <= 0) return ;
await sleep(100);
return onApplicationStart(cb);
}
(async () => {
return onApplicationStart(async () => {
return startQueue()
})
})()
但这是暂时的 hack 而不是解决方案。完整示例:
Nexus 不支持依赖副作用的 Eager 模块代码。
参见:
- https://www.nexusjs.org/#/tutorial/chapter-2-writing-your-first-schema?id=reflection
- https://github.com/graphql-nexus/nexus/issues/758
现在的解决方法是像这样包装您的代码:
// app.ts
if (!process.env.NEXUS_REFLECTION) {
yourHeavyAsyncCode()
}
引用https://github.com/graphql-nexus/nexus/issues/732#issuecomment-626586244
我使用 nexus graphql 框架创建了超级简单的应用程序。
第一步是这样的:
https://www.nexusjs.org/#/tutorial/chapter-1-setup-and-first-query
我api/app.ts
我输入了代码:
const uid = require('uid')
let i = 0;
const sleep = async (ms: number) => {
return new Promise((resolve, reject) => {
setTimeout(resolve, ms)
})
}
const recurrenceFunction = async (id:string): Promise<void> => {
i++;
console.log(id, i);
await sleep(2000);
return recurrenceFunction(id)
}
const startQueue = () => {
const id:string = uid();
return recurrenceFunction(id)
}
(async () => {
return startQueue()
})()
唯一的依赖项是生成唯一键的 uid
。
当我 运行 它与 ts-node 我可以看到:
所以我们可以看到:
- 一旦队列开始。
- 只有一个队列。
- 它正常工作。
但是当我 运行 通过命令 nexus
使用 nexus
这段代码时 nexus dev
我看到了:
所以:
- 两个队列已启动。
- 他们同时运行宁。
- 他们已经独立创建了变量
i
。
问题:
- 有人遇到过这个问题吗?
- 我应该如何更改我的代码以获得像
ts-node
中那样的单队列? - 或者可能是
nexus
的错误?
更新:
我检查过 >= 0.21.1-next.2
在0.21.1-next.1
应用运行s单次。
重现步骤:
nexus dev
npm i nexus@0.21.1-next.1
nexus dev
npm i nexus@0.21.1-next.2
有引入此行为的提交:
https://github.com/graphql-nexus/nexus/commit/ce1d45359e33af81169b7ebdc7bee6718fe313a8
有 onMainThread
和 REFLECTION_ENV_VAR
之类的变量,但没有对文档的引用。我不明白这段代码在做什么?
这可能会在未来记录在这个地方:
https://www.nexusjs.org/#/architecture?id=build-flow
但现在有:
更新 2
我找到了解决方法:
const xid = uid();
let limit=10;
const onApplicationStart = async (cb: () => any):Promise<any> => {
console.log("can i start?", xid, limit, app.private.state.running);
if(app.private.state.running) {
await cb()
return;
}
limit--;
if(limit <= 0) return ;
await sleep(100);
return onApplicationStart(cb);
}
(async () => {
return onApplicationStart(async () => {
return startQueue()
})
})()
但这是暂时的 hack 而不是解决方案。完整示例:
Nexus 不支持依赖副作用的 Eager 模块代码。
参见:
- https://www.nexusjs.org/#/tutorial/chapter-2-writing-your-first-schema?id=reflection
- https://github.com/graphql-nexus/nexus/issues/758
现在的解决方法是像这样包装您的代码:
// app.ts
if (!process.env.NEXUS_REFLECTION) {
yourHeavyAsyncCode()
}
引用https://github.com/graphql-nexus/nexus/issues/732#issuecomment-626586244