为了账号安全,请及时绑定邮箱和手机立即绑定

Promise 如何改变函数的使用

Promise 如何改变函数的使用

慕莱坞森 2023-12-14 15:11:35
我很难找到 Promise 的用途。下面这两种方法的工作方式不是完全相同吗?由于while循环loopTest()是同步的,logStatement()无论如何函数在完成之前都不会运行,所以第二种方法会有什么不同..等待它是没有意义的吗resolve()?第一种方法:function loopTest() {   while ( i < 10000 ) {       console.log(i)       i++   })}function logStatement() {     console.log("Logging test")}loopTest();logStatement();第二种方法:function loopTest() {   return new Promise((resolve, reject) => {      while ( i < 10000 ) {          console.log(i)          i++          if (i === 999) {           resolve('I AM DONE')          }      })   });   }function logStatement() {     console.log("Logging test")}loopTest().then(logStatement());
查看完整描述

4 回答

?
明月笑刀无情

TA贡献1828条经验 获得超4个赞

承诺不会使任何事情异步,所以你是对的,在你所展示的代码中使用承诺是没有意义的。

Promise 的目的是提供一种标准的、可组合的方法来观察异步事物(如 ajax 调用)的结果。

使用标准化方法来观察异步操作的结果至少有三个巨大的好处:

  • 我们可以使用标准语义来使用各个 Promise,而不是每个 API 都为回调函数定义自己的签名。(它是否使用成功时的初始参数发出错误信号null,如 Node.js?它是否使用带有成功标志的对象调用回调?或者...)

  • 我们可以有标准的方式来组合它们,例如Promise.allPromise.racePromise.allSettled等。

  • 我们可以使用语法来使用通常的控制结构来使用它们,这些控制结构现在以async函数 和 的形式存在await

但同样,在同步过程中抛出一个承诺几乎永远不会做任何有用的事情。²


1 一个非常小的警告:附加到 Promise 的处理函数总是异步触发,无论 Promise 是否已经解决。

² 另一个小警告:有时,您希望将同步结果包含在Promise.all具有各种异步操作的组合操作(等)中。在这种情况下,将值包装在立即履行的 Promise 中是有用的 - 事实上,所有标准 Promise 组合器(Promise.all等)都会为您执行此操作,就像 一样await


查看完整回答
反对 回复 2023-12-14
?
慕后森

TA贡献1802条经验 获得超5个赞

这是如何使用 Promise 的更好示例吗?这就是我能想到的让它对我有用的全部:


版本1


function getData() {


   fetch('https://jsonplaceholder.typicode.com/todos/1')

   .then(data => data.json())

   .then(json => console.log(json))

  

}



function logInfo() {

     console.log("i am a logger")

}


getData()

logInfo()


// "I am a logger"

//  {"test": "json"}

版本2


function getData() {


   return fetch('https://jsonplaceholder.typicode.com/todos/1')

   .then(data => data.json())

   .then(json => console.log(json))

  

}



function logInfo() {

     console.log("i am a logger")

}


getData().then(logInfo);

// "{"test": "json"}

// "I am a logger"

// waits for API result to log _then_ logInfo is run , which makes a log statement


查看完整回答
反对 回复 2023-12-14
?
慕斯王

TA贡献1864条经验 获得超2个赞

使用 Promise 肯定有好处,但这只是在某些情况下,它们的使用似乎可行。


您的示例可以表示当您同步从外部源检索数据时会发生什么,它会阻止线程执行进一步的代码,直到循环终止(我在下面解释为什么会发生这种情况) - 将其包装在承诺中不会给出不同的输出因为线程仍然被阻塞,并且当必须处理队列中的下一条消息时,它会在结束后立即像平常一样进行处理。


然而,与此类似的实现可以实现以非阻塞方式运行的 while 循环,这只是一个想法(并不意味着用 setInterval 的实现来破坏这个主题):


let f = () => {

  let tick = Date.now;

  let t = tick();

  let interval = setInterval(() => {

    if (tick() - t >= 3000) {

      console.log("stop");

      clearInterval(interval);

    }

  }, 0);

};

f()

console.log("start");

基本上,时间是在浏览器中的单独线程中检查/处理的,并且在调用堆栈变空之后,每次指定的时间用完而间隔尚未清除时都会执行回调(因此 UI 功能不受影响)当前正在执行的函数终止/结束或在堆栈中其上方的其他函数完成运行之后。我不知道这样做对性能的影响,但我觉得这应该只在必要时使用,因为回调必须非常频繁地执行(超时为 0,尽管无论如何都不能保证为 0) 。

为什么会发生

我主要想澄清的是,虽然处理程序函数将被安排为异步执行,但队列中的每条消息都必须在下一条消息之前完全处理,并且在 while 循环执行期间,事件中不能处理新消息因此,如果没有 Promise,同样的事情也会发生,那么涉及 Promise 是毫无意义的。

所以基本上答案是:

等待它解析()不是毫无意义吗?

是的,在这种情况下这是毫无意义的。


查看完整回答
反对 回复 2023-12-14
?
月关宝盒

TA贡献1772条经验 获得超5个赞

你所做的事情没有任何意义,因为你的函数体只是一个阻塞循环。

要从 Promises 中获益,请将其与执行 IO 操作的 API 结合使用,例如 HTTP 请求或从磁盘读取文件。

这些 API 传统上都使用回调,现在大多基于 Promise。

任何使用基于 Promise 的函数的函数本身也应该是基于 Promise 的。这就是为什么您会在现代代码中看到很多 Promise,因为 Promise 只需要在堆栈中的第 1 层使用,整个堆栈本质上就是异步的。


查看完整回答
反对 回复 2023-12-14
  • 4 回答
  • 0 关注
  • 116 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信