js中promise的使用与理解,js中promise的用法总结

  js中promise的使用与理解,js中promise的用法总结

  本文已经给大家带来了一些关于javascript的知识,包括Promise的基本概念以及使用它的相关问题,包括Promise的基本概念,使用Promise解决回调地狱等。来看看吧,希望对你有帮助。

  【相关推荐:javascript视频教程,web前端】

  

一、前言

  异步是为了提高CPU利用率,让它一直忙。

  有些操作(最典型的就是I/O)本身是不需要CPU参与的,而且非常耗时。如果不使用异步,会造成阻塞状态,CPU空转,页面卡住。

  当异步环境下发生I/O操作时,CPU将I/O工作抛在一边(此时I/O由其他控制器接管,数据仍在传输中),然后处理下一个任务,并在I/O操作完成后通知CPU(回调是一种通知方式)回来工作。

  055-79000的核心内容是异步工作的具体结束时间不确定。为了在异步工作完成后准确地进行后续处理,需要向异步函数发送回调,以便在工作完成后继续后续任务。

  虽然回调可以很简单的实现异步,但是会因为多重嵌套而形成回调地狱。为了避免回调地狱,我们需要取消嵌套,将嵌套编程改为线性编程。

  Promise是JavaScript中处理回调地狱的最佳解决方案。

  

二、Promise基本概念

   Promise可以翻译为“许诺”。我们可以把异步工作封装成一个承诺,承诺在异步工作结束后给出一个明确的信号!

  承诺语法:

  让承诺=新承诺(功能(解决,拒绝){

  //异步工作})通过上面的语法,我们可以把异步工作封装成一个承诺。创建Promise时传入的函数是处理异步工作的方法,也称为executor。

  Resolve和reject是JavaScript本身提供的回调函数,可以在执行器完成任务时调用:

  Lve (result) 3354如果成功完成,返回结果result;Reject(error)——如果执行失败,会产生一个错误;执行人会在承诺创建后立即自动执行,其执行状态会改变承诺内部属性的状态:

  State——最初是挂起的,然后在resolve被调用或拒绝后变为已完成;调用reject时;Result——最初是未定义的,然后在调用resolve(value)后变成value,或者在调用reject后变成error

2.1 异步工作的封装

  文件模块的fs.readFile是一个异步函数。我们可以通过在执行器中执行文件读取操作来实现异步工作的封装。

  下面的代码封装了fs.readFile函数,并使用resolve(data)处理成功的结果,使用reject(err)处理失败的结果。

  代码如下:

  let promise=new Promise((解决,拒绝)={

  fs.readFile(1.txt ,(err,data)={

  Console.log (read 1.txt )

  如果(错误)拒绝(错误)

  解析(数据)

  }}})如果我们执行这段代码,就会输出“Read 1.txt”这几个字,证明文件读取操作是在承诺创建后立即执行的。

  

2.2 Promise执行结果获取

  上面的Promise case封装了读取文件的操作,文件会在创建完成后立即被读取。如果想得到承诺执行的结果,需要使用then、catch和finally。

  

then

   Promise的then方法可用于处理Promise执行完成后的工作。它接收两个回调参数,语法如下:

  Promise.then (function (result),function (error))第一个回调函数用来处理执行成功后的结果,参数result是resolve接收的值;第二个回调函数用于处理执行失败后的结果,参数error是reject收到的参数;示例:

  let promise=new Promise((解决,拒绝)={

  fs.readFile(1.txt ,(err,data)={

  Console.log (read 1.txt )

  如果(错误)拒绝(错误)

  解析(数据)

  })})无极.诡(

  (数据)={

  Console.log(成功执行,结果为 data.toString())

  },

  (错误)={

  Console.log(执行失败,出现错误 err.message)

  })如果成功执行文件读取,将调用第一个函数:

  PS E:\ Code \ Node \ demos \ 03-回调节点。\index.js

  1.txt读取

  执行成功,结果是1删除1.txt如果执行失败,会调用第二个函数:

  PS E:\ Code \ Node \ demos \ 03-回调节点。\index.js

  1.txt读取

  执行失败,出现错误enoent:没有这样的文件或目录,请打开“e:\ code \ node \ demos \ 03-callback \ 1 . txt”。如果我们只关注成功执行的结果,我们可以只传入一个回调函数:

  promise.then((数据)={

  Console.log(执行成功,结果为 data.toString())})这里我们实现了文件的异步读取操作。

  

catch

  如果我们只关注失败的结果,我们可以将第一个then的回调传递给null: promise.then (null,(err)={.}).

  或者用一种更优雅的方式:promise.catch((err)={.})

  let promise=new Promise((解决,拒绝)={

  fs.readFile(1.txt ,(err,data)={

  Console.log (read 1.txt )

  如果(错误)拒绝(错误)

  解析(数据)

  })})promise.catch((err)={

  Console.log (err.message)})。catch ((err)={.})然后是(null,(err)={.})的作用完全一样。

  :

finally

   .最后是一个不管结果如何,promise都会执行的功能。喜欢在try中使用finally.捕捉.语法,它可以处理与结果无关的操作。

  例如:

  新承诺((解决,拒绝)={

  //什么的.}).最后(()={console.log(执行不管结果)})。然后(结果={.},错误={.}) Finally callback没有参数,不管成功与否都会执行。最终会兑现承诺,所以最终还是有可能的。然后

三、使用Promise解决回调地狱

  

3.1 回调地狱出现的场景

  现在我们有一个要求:用fs.readFile()方法依次读取10个文件,依次输出这十个文件的内容。

  由于fs.readFile()本身是异步的,所以我们必须使用回调嵌套。代码如下:

  fs.readFile(1.txt ,(err,data)={

  console . log(data . tostring())//1

  fs.readFile(2.txt ,(err,data)={

  console.log(data.toString())

  fs.readFile(3.txt ,(err,data)={

  console.log(data.toString())

  fs.readFile(4.txt ,(err,data)={

  console.log(data.toString())

  fs.readFile(5.txt ,(err,data)={

  console.log(data.toString())

  fs.readFile(6.txt ,(err,data)={

  console.log(data.toString())

  fs.readFile(7.txt ,(err,data)={

  console.log(data.toString())

  fs.readFile(8.txt ,(err,data)={

  console.log(data.toString())

  fs.readFile(9.txt ,(err,data)={

  console.log(data.toString())

  fs.readFile(10.txt ,(err,data)={

  console.log(data.toString())

  //==地狱之门

  })

  })

  })

  })

  })

  })

  })

  })

  }}})虽然上面的代码可以完成任务,但是随着调用嵌套的增加,代码层次变深,维护难度增加。特别是,我们使用可能包含许多循环和条件语句的真实代码,而不是简单的console.log(.)的例子中。

  

3.2 不使用回调产生的后果

  如果我们不使用回调,直接按照下面的代码调用fs.readFile()会怎么样?

  //注意:这是写fs.readfile (1.txt ,(err,data)={

  console . log(data . tostring())})fs . readfile( 2 . txt ,(err,data)={

  console . log(data . tostring())})fs . readfile( 3 . txt ,(err,data)={

  console . log(data . tostring())})fs . readfile( 4 . txt ,(err,data)={

  console . log(data . tostring())})fs . readfile( 5 . txt ,(err,data)={

  console . log(data . tostring())})fs . readfile( 6 . txt ,(err,data)={

  console . log(data . tostring())})fs . readfile( 7 . txt ,(err,data)={

  console . log(data . tostring())})fs . readfile( 8 . txt ,(err,data)={

  console . log(data . tostring())})fs . readfile( 9 . txt ,(err,data)={

  console . log(data . tostring())})fs . readfile( 10 . txt ,(err,data)={

  Console.log (data.tostring ()})下面是我测试的结果(每次执行的结果都不一样):

  PS:\ code \ node \ demos \ 03-回调节点。\ index.js12346957108原因是异步产生这种非顺序结果的不是多线程并行,而是异步可以在单线程中实现。

  这里之所以使用这个错误的案例,是为了强调异步的概念。不明白为什么会出现这种结果,一定要回去补课!

  

3.3 Promise解决方案

  利用Promise解决异步顺序文件读取的思想;

  封装文件以读取promises 1,并使用resolve返回结果。使用Promethe1.then接收并输出文件读取结果。在Promethe1.then中创建一个新的promise2对象,返回调用新的Promethe2.then接收并输出读取结果。在Promethe2.then中创建一个新的promise3对象,返回调用新的promise3.then接收并输出读取结果…代码如下:

  let promise1=新承诺((解决,拒绝)={

  fs.readFile(1.txt ,(err,data)={

  如果(错误)拒绝(错误)

  解析(数据)

  )let promise2=promise1.then(

  数据={

  console.log(data.toString())

  返回新承诺((解决,拒绝)={

  fs.readFile(2.txt ,(err,data)={

  如果(错误)拒绝(错误)

  解析(数据)

  })

  })

  })let promise3=promise2.then(

  数据={

  console.log(data.toString())

  返回新承诺((解决,拒绝)={

  fs.readFile(3.txt ,(err,data)={

  如果(错误)拒绝(错误)

  解析(数据)

  })

  })

  })let promise4=promise3.then(

  数据={

  console.log(data.toString())

  //.

  }

  然而,代码仍然存在一个问题。虽然代码在管理上变漂亮了,但是大大增加了代码的长度。

  

3.4 链式编程

  以上的代码太冗长,我们可以通过两步来减少代码量:

  用重复的函数封装代码,完成文件读取和输出,中间省略promise的变量创建,链接。然后。代码如下:

  函数myReadFile(路径){

  返回新承诺((解决,拒绝)={

  fs.readFile(路径,(错误,数据)={

  如果(错误)拒绝(错误)

  console.log(data.toString())

  解决()

  })

  })}myReadFile(1.txt )。然后(data={ return my read file( 2 . txt )})。然后(data={ return my read file( 3 . txt )})。然后(data={ return my read file( 4 . txt )})。然后(data={ return my read file( 5 . txt )})。然后(data={ return my read file( 6 . txt )})。然后(data={ return my read file( 7 . txt )})。然后(data={ return my read file( 8 . txt )})。然后(data={ return my read file( 9 . txt )})。然后(data={ return myReadFile( 10 . txt )})由于my read file方法会返回一个新的承诺,所以我们可以直接执行。然后方法。这种编程方法叫做链式编程

  代码执行结果如下:

  PS:\ code \ node \ demos \ 03-回调节点。\ index.js12345678910这样,异步和顺序文件读取操作就完成了。

  【相关推荐:javascript视频教程,web前端】以上是对JavaScript中Promise的基本概念和用法的详细介绍。更多请关注我们的其他相关文章!

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: