当前位置: 首页 > news >正文

Nuxt3: useFetch使用过程常见一种报错

一、问题描述

先看一段代码:

<script setup>
const fetchData = async () => {const { data, error } = await useFetch('https://api.publicapis.org/entries');const { data: data2, error: error2 } = await useFetch('https://api.publicapis.org/entries');
};await fetchData(); // if you remove await the app will start, but server terminal will return same error
</script><template><div><NuxtWelcome /></div>
</template>

这段代码在不同的Nuxt版本的报错会有不同,但本质是一样的问题:

Nuxt 3.1.1:

nuxt instance unavailable

在这里插入图片描述
Nuxt 3.10.3:

[nuxt] A composable that requires access to the Nuxt instance was called outside of a plugin, Nuxt hook, Nuxt middleware, or Vue setup function. This is probably not a Nuxt bug. Find out more at `https://nuxt.com/docs/guide/concepts/auto-imports#vue-and-nuxt-composables`.

在这里插入图片描述

也可以直接访问https://stackblitz.com/edit/github-qe9ulj-opndzv?file=app.vue,在线运行代码,查看结果。

这个问题,在之前的文章《Nuxt: A composable that requires access to the Nuxt instance was called outside of a plugin…》有提到过,这次针对useFetch的使用再次遇到该问题,就再花点时间进行记录。

之所以关注到该问题,是因为对useFetch封装后,在页面setup中调用时(以某种特定的方式进行),出现了上述的错误。

为了更好的描述问题,先简单看一段能正常运行的代码:

<script setup>
const fetchData = async () => {const { data, error } = await useFetch('https://api.publicapis.org/entries');
};await fetchData(); // if you remove await the app will start, but server terminal will return same error
</script><template><div><NuxtWelcome /></div>
</template>

这段代码与之前的相比,唯一差别就是async fetchData 内只出现了一次await useFetch的调用,但它却能正常运行:

在这里插入图片描述
一旦async fetchData 内多了一次await useFetch调用,就直接报错了:

在这里插入图片描述
但如果再换另一种方式就又正常了:

<script setup>
const fetchData = async () => {const res = await Promise.all([useFetch('https://api.publicapis.org/entries'),useFetch('https://api.publicapis.org/entries'),]);
};await fetchData(); // if you remove await the app will start, but server terminal will return same error
</script><template><div><NuxtWelcome /></div>
</template>

在这里插入图片描述
而一旦在await Promise.all之后再添加useFetch的调用就立马又报错:
在这里插入图片描述

这个问题在此看似乎可以描述为:在方法内多次调用useFetch,会导致错误
正好有一篇《Nuxt 3 useFetch - nuxt instance unavailable when using useFetch at least twice in one function》提到了这样的观点,之前的代码也是来源于此。但它的标题描述的不够准确,因为不是在方法内多次调用useFetch就一定会有问题,比如:
在这里插入图片描述
上面这样就很正常,那么出问题的地方就在于是否使用了await。为了验证这个想法,先只给第一个useFetch加上await

在这里插入图片描述
接下来,只给第二个useFetch加上await
在这里插入图片描述

至此,该问题可以描述为:在方法内一旦出现了await useFetch之后,再有useFetch的调用就会报错。

二、问题调查

前面问题描述了比较长的过程,而关于此问题也有人提到:

After calling useFetch within a function the context is lost - it should be called either directly within your setup block (in which case the context will be preserved - or you can use callWithNuxt. More info here: #14269 (comment).

在 #14269 里最后提到nuxtApp.runWithContext #23258

根据这些,可以猜测:应该是因为在useFetch在不恰当调用环境下,nuxt的context丢失,导致useFetch报错。

我们找到runWithContext的文档看看:

You are likely here because you got a “Nuxt instance unavailable” message. Please use this method sparingly, and report examples that are causing issues, so that it can ultimately be solved at the framework level.

The runWithContext method is meant to be used to call a function and give it an explicit Nuxt context. Typically, the Nuxt context is passed around implicitly and you do not need to worry about this. However, when working with complex async/await scenarios in middleware/plugins, you can run into instances where the current instance has been unset after an async call.

该runWithContext方法旨在用于调用函数并为其提供显式 Nuxt 上下文。通常,Nuxt 上下文会隐式传递,您无需担心这一点。但是,在处理中间件/插件中的复杂async/await场景时,您可能会遇到异步调用后当前实例已取消设置的情况。

A Deeper Explanation of Context
Vue.js Composition API (and Nuxt composables similarly) work by depending on an implicit context. During the lifecycle, Vue sets the temporary instance of the current component (and Nuxt temporary instance of nuxtApp) to a global variable and unsets it in same tick. When rendering on the server side, there are multiple requests from different users and nuxtApp running in a same global context. Because of this, Nuxt and Vue immediately unset this global instance to avoid leaking a shared reference between two users or components.

Vue.js Composition API(以及类似的 Nuxt 组合函数)通过依赖隐式上下文来工作。在生命周期中,Vue 将当前组件的临时实例(以及 nuxtApp 的 Nuxt 临时实例)设置为全局变量,并在同一Tick阶段销毁。在服务器端渲染时,有来自不同用户的多个请求,并且 nuxtApp 在同一全局上下文中运行。因此,Nuxt 和 Vue 立即取消设置此全局实例,以避免泄漏两个用户或组件之间的共享引用。

里面提到in same tick,这里的tick应该是跟Node Tick类似:

event loop 的每次迭代,在nodejs 中就叫做 “Tick” 。
在Node.js中,事件循环是一个持续运行的过程,负责处理事件和执行回调函数。事件循环包含了不同的阶段,其中之一就是"tick"阶段。在每个"tick"阶段,Node.js会执行以下几个主要任务:

  1. 执行微任务(microtasks):在每个"tick"阶段开始时,Node.js会首先执行所有微任务队列中的任务。微任务通常包括Promise回调、process.nextTick()等。
  2. 执行定时器检查:Node.js会检查定时器队列,查看是否有定时器到期需要执行。如果有定时器到期,Node.js会将其回调函数放入事件队列中,等待下一个"tick"阶段执行。
  3. 执行IO操作:Node.js会处理已经完成的IO操作的回调函数。这包括文件读写、网络请求等异步操作的回调函数。
  4. 执行事件回调:Node.js会执行事件队列中的事件回调函数。这些事件可能是由网络请求、定时器、IO操作等触发的。
  5. 检查是否需要继续下一个"tick"阶段:在当前"tick"阶段执行完毕后,Node.js会检查是否需要继续下一个"tick"阶段。如果事件队列中还有待处理的事件,Node.js会继续执行下一个"tick"阶段。

通过这样的"tick"阶段循环,Node.js能够高效地处理异步操作和事件回调,保证应用程序的响应性和性能。

再结合有关Vue and Nuxt composables的文档介绍:

Vue and Nuxt composables
When you are using the built-in Composition API composables provided by Vue and Nuxt, be aware that many of them rely on being called in the right context.
During a component lifecycle, Vue tracks the temporary instance of the current component (and similarly, Nuxt tracks a temporary instance of nuxtApp) via a global variable, and then unsets it in same tick. This is essential when server rendering, both to avoid cross-request state pollution (leaking a shared reference between two users) and to avoid leakage between different components.
That means that (with very few exceptions) you cannot use them outside a Nuxt plugin, Nuxt route middleware or Vue setup function. On top of that, you must use them synchronously - that is, you cannot use await before calling a composable, except within

当您使用 Vue 和 Nuxt 提供的内置 Composition API 组合函数时,请注意它们中的许多都依赖于在正确的上下文中调用。
在组件生命周期中,Vue 通过全局变量跟踪当前组件的临时实例(类似地,Nuxt 跟踪nuxtApp的临时实例),然后在同一Tick阶段销毁。这在服务器渲染时至关重要,既可以避免交叉请求状态污染(泄漏两个用户之间的共享引用),又可以避免不同组件之间的泄漏。
这意味着(除了极少数例外)你不能在 Nuxt 插件、Nuxt 路由中间件或 Vue 设置函数之外使用它们。最重要的是,您必须同步使用它们 - 也就是说,您不能在组合函数前使用await关键字,除非在<script setup>块内,在使用以defineNuxtComponent方式声明的组件的setup函数内,在defineNuxtPlugin或者defineNuxtRouteMiddleware中,这些地方即使在await后我们会执行一个转换以保持同步上下文。

也就是说,在<script setup>内,直接调用useFetch,即使useFetch前面使用await关键字也能正常访问到Nuxt Context,所以这种情况下它都能正常运行,这也是你为什么看到的useFetch的使用示例大多如此的原因:

在这里插入图片描述

通过上述介绍,现在可以知道之前描述的种种问题产生的原因,是因为在useFetch前使用await关键字,会导致它们处于不同的Tick阶段,而无法访问Nuxt Context引起报错。

相关文章:

Nuxt3: useFetch使用过程常见一种报错

一、问题描述 先看一段代码&#xff1a; <script setup> const fetchData async () > {const { data, error } await useFetch(https://api.publicapis.org/entries);const { data: data2, error: error2 } await useFetch(https://api.publicapis.org/entries);…...

当代计算机语言占比分析

在当今快速发展的科技领域&#xff0c;计算机语言作为程序员的工具之一&#xff0c;扮演着至关重要的角色。随着技术的不断演进&#xff0c;各种编程语言层出不穷&#xff0c;但在实际开发中&#xff0c;哪些计算机语言占据主导地位&#xff1f;本文将对当代计算机语言的占比进…...

基于大模型和向量数据库的 RAG 示例

1 RAG 介绍 RAG是一种先进的自然语言处理方法&#xff0c;它结合了信息检索和文本生成技术&#xff0c;用于提高问答系统、聊天机器人等应用的性能。 2 RAG 的工作流程 文档加载&#xff08;Document Loading&#xff09; 从各种来源加载大量文档数据。这些文档…...

【C语言】比较两个字符串大小,strcmp函数

目录 一&#xff0c;strcmp函数 1&#xff0c;strcmp函数 2&#xff0c;函数头文件&#xff1a; 3&#xff0c;函数原型&#xff1a; 4&#xff0c;返回取值&#xff1a; 二&#xff0c;代码实现 三&#xff0c;小结 一&#xff0c;strcmp函数 1&#xff0c;strcmp函数 …...

深入理解与应用Keepalive机制

目录 引言 一、VRRP协议 &#xff08;一&#xff09;VRRP概述 1.诞生背景 2.基本理论 &#xff08;二&#xff09;VRRP工作原理 &#xff08;三&#xff09;VRRP相关术语 二、keepalive基本理论 &#xff08;一&#xff09;基本性能 &#xff08;二&#xff09;实现原…...

嵌入(embedding)概念

嵌入&#xff08;embedding&#xff09;在数学和相关领域中的确是指将一个数学对象在保持其某些关键性质不变的前提下&#xff0c;注入到一个更大或更高维的空间中。这个过程不仅仅是简单的映射&#xff0c;而是要求注入的对象在新空间中的表现形式能够完整反映原有对象的内在结…...

豆瓣书影音存入Notion

使用Python将图书和影视数据存放入Notion中。 &#x1f5bc;️介绍 环境 Python 3.10 &#xff08;建议 3.11 及以上&#xff09;Pycharm / Vs Code / Vs Code Studio 项目结构 │ .env │ main.py - 主函数、执行程序 │ new_book.txt - 上一次更新书籍 │ new_video.…...

Lucene 分词 示例代码

import org.apache.lucene.analysis.tokenattributes.CharTermAttribute; import org.apache.lucene.analysis.TokenStream; import org...

2.18 校招 实习 内推 面经

绿*泡*泡VX&#xff1a; neituijunsir 交流*裙 &#xff0c;内推/实习/校招汇总表格 1、自动驾驶一周资讯 - 李想回应“年终奖有点大”&#xff1b;智界升级为奇瑞独立事业部&#xff1b;小鹏汽车春节累计智驾总里程公布 自动驾驶一周资讯 - 李想回应“年终奖有点大”&…...

spring中事务失效的场景有哪些?

异常捕获处理 在方法中已经将异常捕获处理掉并没有抛出。 事务只有捕捉到了抛出的异常才可以进行处理&#xff0c;如果有异常业务中直接捕获处理掉没有抛出&#xff0c;事务是无法感知到的。 解决&#xff1a;在catch块throw抛出异常。 抛出检查异常 spring默认只会回滚非检…...

Visual Studio 2022之Release版本程序发送到其它计算机运行

目录 1、缺少dll​ 2、应用程序无法正常启动 3、This application failed to start because no Qt platform plugin could be initialized. 代码在Debug模式下正常运行&#xff0c;然后切换到Release模式下&#xff0c;也正常运行&#xff0c;把第三方平台的dll拷贝到exe所在…...

Xcode下载模拟器报错Could not download iOS 17.4 Simulator (21E213).

xcode14以后最小化安装包&#xff0c;从而将模拟器不集中在安装包中 因此xcode14至以后的版本安装后第一次启动会加载提示安装模拟器的提示框 或者根据需要到xcode中进行所需版本|平台的模拟器进行安装 Xcode > Settings > Platforms 问题来了尝试多次都安装失败例如…...

mac在终端设置代理

前言 本篇文章介绍如何在mac终端设置代理服务器&#xff0c;有时候&#xff0c;我们需要在终端进行外网的资源访问&#xff0c;比如我构建v8引擎项目的时候&#xff0c;需要使用gclient更新组件和下载构建工具。如果单单设置了计算机的代理&#xff0c;依然是无法下载资源的&a…...

傅立叶之美:深入研究傅里叶分析背后的原理和数学

一、说明 T傅里叶级数及其伴随的推导是数学在现实世界中最迷人的应用之一。我一直主张通过理解数学来理解我们周围的世界。从使用线性代数设计神经网络&#xff0c;从混沌理论理解太阳系&#xff0c;到弦理论理解宇宙的基本组成部分&#xff0c;数学无处不在。 当然&#xff0c…...

golang学习随便记16-反射

为什么需要反射 下面的例子中编写一个 Sprint 函数&#xff0c;只有1个参数&#xff08;类型不定&#xff09;&#xff0c;返回和 fmt.Fprintf 类似的格式化后的字符串。实现方法大致为&#xff1a;如果参数类型本身实现了 String() 方法&#xff0c;那调用 String() 方法即可…...

识别恶意IP地址的有效方法

在互联网的环境中&#xff0c;恶意IP地址可能会对网络安全造成严重威胁&#xff0c;例如发起网络攻击、传播恶意软件等。因此&#xff0c;识别恶意IP地址是保护网络安全的重要一环。IP数据云将探讨一些有效的方法来识别恶意IP地址。 IP地址查询&#xff1a;https://www.ipdata…...

探索信号处理:低通滤波器的原理与应用

在信号处理领域&#xff0c;滤波器的应用至关重要&#xff0c;它能够帮助我们从复杂的信号中提取需要的信息&#xff0c;而低通滤波器则是其中一种被广泛应用的滤波器类型。本文旨在深入探讨低通滤波器的基本原理、主要类型以及在实际应用中的作用和实现方式。 ### 1. 低通滤波…...

计算机网络:应用层知识点汇总

文章目录 一、网络应用模型二、域名系统&#xff08;DNS&#xff09;三、文本传输协议&#xff08;FTP&#xff09;四、电子邮件五、万维网和HTTP协议 一、网络应用模型 p2p也就是对等模型 二、域名系统&#xff08;DNS&#xff09; 我们知道&#xff0c;随着人们建立一个网站…...

金三银四!一个年薪160W+的就业方向!

前言 随着越来越多的科技大厂加入鸿蒙生态建设&#xff0c;鸿蒙开发人才正在市场上被争抢。资深工程师开出的年薪高达近百万&#xff0c;架构师更是高至160万&#xff0c;真可谓“鸿蒙猿年薪超百万”。如何抓住新技术红利&#xff0c;尽早上车&#xff1f;你会成为下一个鸿蒙开…...

实现的一个网页版的简易表白墙

实现的一个网页版的表白墙 实现效果 代码截图 相关代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><tit…...

Docbox实战案例分享:Mapbox、Mapillary等知名公司的使用经验

Docbox实战案例分享&#xff1a;Mapbox、Mapillary等知名公司的使用经验 【免费下载链接】docbox REST API documentation generator 项目地址: https://gitcode.com/gh_mirrors/do/docbox Docbox是一款开源的REST API文档生成系统&#xff0c;它能够将结构化的Markdown…...

告别美术字烦恼!Unity UGUI自定义图片字体保姆级教程(附完整工具代码)

Unity UGUI自定义图片字体全流程实战指南在游戏UI开发中&#xff0c;标准字体往往无法满足美术设计的个性化需求。当遇到特殊风格的数字、符号或文字时&#xff0c;传统解决方案要么依赖美术逐张制作图片&#xff0c;要么忍受字体版权和风格限制。本文将彻底解决这个痛点——通…...

从“画箭头”到1亿播放量:机械工程师梁乐平,如何用CAD绘图书写知识传播新篇章?

一、绘图的开始和许多人一样&#xff0c;梁乐平选择了机械类专业&#xff0c;从广东理工学院毕业后&#xff0c;一头扎进了机械设计与绘图的世界。与别人不同的是&#xff0c;他给自己取了一个颇有传统文人气息的字“金泓”。这个细节&#xff0c;隐约透露着他性格中那份既务实…...

紧急更新!OpenAI API v4.5对脑筋急转弯类输出新增隐式过滤机制——立即启用这7个绕过策略,保住你的创意产能

更多请点击&#xff1a; https://codechina.net 第一章&#xff1a;OpenAI API v4.5脑筋急转弯过滤机制的底层原理与影响评估 OpenAI API v4.5 引入的脑筋急转弯过滤机制并非独立模块&#xff0c;而是深度集成于请求预处理与响应后置校验双阶段的语义安全策略。其核心依赖于轻…...

矩阵补全因果推断:破解贸易政策评估中的内生性与异质性难题

1. 项目概述&#xff1a;当因果推断遇上贸易政策评估的“硬骨头”做贸易政策评估的同行都知道&#xff0c;这事儿有多棘手。你想啊&#xff0c;一个国家签了个自由贸易协定&#xff08;FTA&#xff09;&#xff0c;几年后出口额涨了&#xff0c;你怎么知道这增长里有多少是协定…...

论文初稿被批太水?青年教师力荐这几个AI论文写作软件

想写论文又快又好&#xff0c;关键是用对 AI 工具、走对流程——资深教授普遍推荐&#xff1a;千笔AI&#xff08;中文全流程首选&#xff09; 豆包学术版&#xff08;轻量高效&#xff09; DeepSeek 学术版&#xff08;理工 / 长文本&#xff09; Grammarly Academic&#xff…...

如何免费解锁Wand专业版功能:Wand-Enhancer完整使用指南

如何免费解锁Wand专业版功能&#xff1a;Wand-Enhancer完整使用指南 【免费下载链接】Wand-Enhancer Advanced UX and interoperability extension for Wand (WeMod) app 项目地址: https://gitcode.com/gh_mirrors/we/Wand-Enhancer 还在为Wand&#xff08;原WeMod&…...

卖瓦楞纸箱怎么找客户?下游工厂在哪里

卖瓦楞纸箱找客户&#xff0c;本质是找用箱量大的下游工厂&#xff0c;核心难点是拿到这些工厂的名单和联系人——因为纸箱是本地化极强的耗材&#xff0c;客户往往就在方圆 100 到 200 公里内&#xff0c;谁先把本地下游工厂版图盘清楚&#xff0c;谁就掌握了竞争主动权。 用箱…...

Solr CVE-2019-0193漏洞深度解析:DataImportHandler远程代码执行原理与实战修复

1. 这个漏洞不是“能远程执行代码”那么简单&#xff0c;而是Solr管理员自己亲手打开的后门 Apache Solr 是企业级搜索领域绕不开的基础设施&#xff0c;我经手过的金融、电商、政务类项目里&#xff0c;有七成以上都用它做全文检索底座。但2019年爆出的 CVE-2019-0193&#xf…...

高斯过程回归与离散变分原理:数据驱动的物理结构发现

1. 项目概述&#xff1a;当高斯过程回归遇见离散变分原理在物理信息机器学习这个交叉领域&#xff0c;我们常常面临一个核心挑战&#xff1a;如何从有限的、可能带有噪声的观测数据中&#xff0c;不仅还原出物理系统的动态&#xff0c;还能揭示其背后深刻的数学结构&#xff1f…...