如何暂停javascript代码执行直到fetch()实际获取文件

如何暂停javascript代码执行直到fetch()实际获取文件,javascript,async-await,fetch-api,Javascript,Async Await,Fetch Api,让我们假设页面上的标准进度从如下窗口加载事件开始 window.addEventListener("load",function(){ doTheseFirst(); }, { once: true }); function doTheseFirst() { setTimeout(function(){ andThenDoThese(); }, 5000); // Maybe show some pictures and play some sounds f

让我们假设页面上的标准进度从如下
窗口加载事件开始

window.addEventListener("load",function(){   doTheseFirst();   }, { once: true });

function doTheseFirst()
{
  setTimeout(function(){ andThenDoThese(); }, 5000);
  // Maybe show some pictures and play some sounds for 5 seconds
}

function andThenDoThese()
{
  // Show other pictures and play other sounds until user clicks OK
  elementOnPageForOK.addEventListener("click", andThenDoTheseTooWhenUserClicksOK);
}

function andThenDoTheseTooWhenUserClicksOK()
{
  // etc etc
  // You get the idea
}
假设这段代码被反复使用。 但在某些情况下,用户必须在执行链开始运行之前看到通知。一个简单的解决方案是使用警报框,因为它会阻止/暂停代码执行。以下代码使警报框在
fetch()
txt
文件中获取内容时立即弹出。请注意,
fetch()
windowload
是独立工作的

fetch("somefolder/notification.txt").then(function(response){return response.text();}).then(function(contentOfTheTxtFile){ alert(contentOfTheTxtFile); });
这是因为当警报框关闭时,主代码会根据需要返回其正常流程

但是,如果不使用我无法指定任何样式的原始警报框,我如何做同样的事情呢? 我是否可以使代码执行在
fetch()
获取文件时立即暂停,然后在用户单击OKNEXT按钮后立即取消暂停

使用async/await是否可以实现这一点


编辑1:进一步澄清 请记住,不确定
fetch()
windowload
是否首先触发完成信号。因为下载速度完全不可预测。 因此,如果我们将它们都设置为这样,我们不知道另一个需要多少毫秒才能赶上

if(thisTimeItIsASpecialCase){
 fetch("somefolder/notification.txt").then(function(response){return response.text();}).then(function(contentOfTheTxtFile){ /*What to do when the file is ready*/ });
}
window.addEventListener("load",function(){   doTheseFirst();   }, { once: true });

实现所需结果的一种简化方法:将
doTheseFirst()
函数挂起,让它等待
fetch()
,如果
fetch()
确实在尝试获取文件,则让它完成获取文件的任务。如果没有回迁操作,也让
doTheseFirst()
继续运行。

您可以在一个漂亮的
或回迁中的任何元素中显示文本文件的内容,然后退出函数。
您可以向按钮添加一个
EventListener
,当用户单击该按钮时,您可以移动到下一个操作。

您可以执行以下操作

  • 您可以定义一些html,在其中显示内容并将其隐藏,直到内容真正可用

  • 您可以定义一个按钮来再次隐藏此元素

  • next
    eventhandler只是用来调用一个Promise-resolve回调,它将在需要时定义

  • 当您的文本可用于将其添加到显示和创建时,请等待单击下一步按钮即可解决的
    新承诺

  • 承诺链中的下一个处理程序再次隐藏显示

这段代码当然是非常基本和示意性的。为了实际使用,您可以将其封装在自己的类或模块中。如果你正在使用一些框架,比如React,Angular。。。有很多组件可以随时使用,它们正好提供了这种功能。例如,作为模态对话框或任何形式

var解析器=未定义;
函数next(){
if(resolver)resolver.call();
}
函数getText(){
取回(“https://baconipsum.com/api/?type=meat-和填充语&第3段&格式=文本)
.then(response=>response.text())
。然后(文本=>{
document.getElementById(“thetext”).innerText=text;
document.getElementById(“显示”).hidden=false;
返回新承诺(解决=>{
分解器=分解;
});
})
.然后(()=>{
document.getElementById(“display”).hidden=true;
解析器=未定义;
})
.catch(e=>console.log(e));
}


这是显而易见的,但这并不是对问题的答案。我知道我们可以使用setInterval每100ms检查一次fetch是否有结果,然后才触发doTheseFirst()和clearInterval。但这不是它应该的方式。这会暂停所有设置超时和设置间隔的滴答声,直到用户点击OK吗?因为警报框可以做到这一点。不,这不会暂停任何超时。唯一可以做的事情是,只有在通过单击按钮履行承诺后,它才会隐藏文本区域。如果您在
获取
窗口之间存在竞争条件。加载
您的应用程序中存在设计问题。如果任务彼此独立启动,则它们不应相互依赖。如果其中一项任务需要其他任务的结果,则必须在另一项任务完成后才能启动该任务。但是从你对问题的描述中,没有人能看出你真正需要的是什么……如果有另一种方法来控制事物的运行方式,我们就不必称之为设计问题。如果什么也做不到警告框所能做的,那么当然我将不得不更改代码的结构。@如果您按照所使用语言的规范正确操作,那么您可以完全控制运行的方式。顺便说一句,使用
警报
等待其他JS函数完成不会起作用。因为JS是单线程的。因此,在显示警报时,不会执行任何其他语句。