Javascript 如果我们通常需要在继续之前处理承诺,为什么不返回已经处理的响应而不是承诺的响应呢?

Javascript 如果我们通常需要在继续之前处理承诺,为什么不返回已经处理的响应而不是承诺的响应呢?,javascript,promise,fetch,Javascript,Promise,Fetch,我读了不少书,看了不少视频,但不幸的是,我的问题还没有找到答案。这让我觉得我的问题被误导了,但我想知道为什么。(注意:我确实觉得有帮助,但答案似乎没有满足我的好奇心。) 如果我理解正确的话,承诺并不是这样起作用的: 朋友:听着,今天结束前,我会给你买台电脑。这是一个承诺 我:太棒了!当你这么做的时候,我会做很多其他的事情 朋友(在一天结束时):这是这个盒子。你只需要打开(处理)它 我打开盒子,如果是空的,我知道她的承诺失败了(被拒绝了)。如果里面有一台电脑,我知道她的承诺是成功的。而且,如果里

我读了不少书,看了不少视频,但不幸的是,我的问题还没有找到答案。这让我觉得我的问题被误导了,但我想知道为什么。(注意:我确实觉得有帮助,但答案似乎没有满足我的好奇心。)


如果我理解正确的话,承诺并不是这样起作用的:

朋友:听着,今天结束前,我会给你买台电脑。这是一个承诺

我:太棒了!当你这么做的时候,我会做很多其他的事情

朋友(在一天结束时):这是这个盒子。你只需要打开(处理)它

我打开盒子,如果是空的,我知道她的承诺失败了(被拒绝了)。如果里面有一台电脑,我知道她的承诺是成功的。而且,如果里面有一张纸条写着“仍在努力履行这一承诺”,我知道她的承诺仍在等待中


相反,承诺的作用似乎是这样的:

朋友:听着,今天结束前,我会给你买台电脑。这是一个承诺

我:好的,我希望尽快得到那台电脑,因为我今天的所有任务都取决于这台电脑。我需要发几封电子邮件,这需要那台电脑。我需要研究获取请求,这也需要您承诺的内容。然后我需要问一个关于StackOverflow的问题,这肯定需要那台机器。所以,我只想等到你的承诺成功或失败(或者你告诉我你需要更多的时间)

然后,朋友带着第一个场景中的同一个盒子返回,因此我需要首先打开盒子(或处理承诺),然后才能执行任何进一步的任务


那么,我的问题是,如果我们需要等待承诺响应,为什么该响应没有得到预先处理?换句话说,为什么我的朋友递给我一个我必须打开的盒子,而不是递给我电脑或者告诉我他们失败了(或者让我知道他们需要更多的时间)

当我发出获取请求时,我不能只使用响应。我需要先
json()
it。或者,我需要先执行
then()
catch()
。为什么我们要返回承诺的数据而不是数据本身(当然,如果成功的话)

我希望这个问题有意义。我期待着我的假设得到纠正

当我发出获取请求时,我不能只使用响应。我需要先把它修好。或者,我需要先抓住它。为什么我们要返回承诺的数据而不是数据本身(当然,如果成功的话)


您不能返回数据本身。主机函数本身在数据可用之前很久就会返回。这就是Javascript中非阻塞异步操作的工作方式。因此,在函数返回时,数据尚未到达。因此,您将返回一个承诺,允许调用方将
.then()
侦听器挂接到该承诺,并在数据实际就绪时收到通知,或者返回
.catch()
侦听器以查看是否存在错误

让我们看一个简单的例子。假设您有一个异步操作,它会返回一些值。您希望创建另一个函数,将该值平方并返回该值

//获取0到9999之间的随机数
函数rand(){
返回Math.floor(Math.random()*10000);
}
函数getValue(){
控制台日志(“5”);
返回新承诺((解决、拒绝)=>{
控制台日志(“6”);
设置超时(()=>{
控制台日志(“7”);
解析(rand());
控制台日志(“8”);
}, 500);
});
}
函数getSquaredValue(){
控制台日志(“3”);
返回getValue()。然后(val=>{
控制台日志(“4”);
返回val*val;
});
}
控制台日志(“1”);
getSquaredValue()。然后(val=>{
log(“获取值”);
}).catch(错误=>{
控制台日志(err);
});

控制台日志(“2”)Javascript正在同步运行,Promise是处理asnyc操作的一种方法。 你如何用承诺来处理它?在
.then()中

。。。同步代码
承诺。然后((someVar)=>{
异步代码将在承诺实现并定义someVar时运行
})
... 同步代码将在履行承诺和未定义someVar之前运行
您可以使用async/await语法将函数定义为异步函数,以实现所需的功能

异步函数someAsyncFunction(){ …同步代码 让someVar=等待承诺(); …异步代码将在承诺实现并定义someVar时运行 }
您的标准html+javascript站点在一个线程中运行。长时间运行的javascript任务将阻止ui接收输入或呈现更新

网络请求可能需要几秒钟的时间。如果我们不得不等待结果3秒钟,那么网站将被冻结3秒钟。相反,web请求在单独的线程上进行内部处理,当web请求完成时(成功或失败),会通知主javascript线程

因此,我们不能等待请求,因为它将冻结站点,但我们还需要能够在web请求到达时接收其结果。简单的原始javascript实现这一点的方式是通过。 下面是一个基本示例,说明它如何处理来自以下站点的web请求:

现在,这与承诺有什么关系?事实上,很多人不喜欢回调,这很容易让人纠结。承诺是旧的基于回调的方法的有效包装。承诺也可以很容易地传递到其他函数和服务中,当承诺解决了所有问题时
//This function is called when the web request completes
function reqListener () {
   console.log(this.responseText);
}

var oReq = new XMLHttpRequest();
oReq.addEventListener("load", reqListener);
oReq.open("GET", "http://www.example.org/example.txt");
oReq.send();