JavaScript异步解决方案之Promise

概念

  • Promise 对象用于表示一个异步操做的最终完成或者失败,以及结果值
  • Promise()是一个构造函数,用于实例化 Promise对象
  • Promise是一种新的写法,而不是新的功能
  • 回调函数自己没有问题,问题是多个回调函数嵌套,容易造成回调地狱,Promise就是为了解决这个问题

语法

// 实例化一个Promise对象
new Promise(
  // excutor 执行器
  function(resolve,reject){}
)
// 使用函数包裹
function createPromise(...){
	return new Promise(
  	function(resolve,reject) ) } 复制代码

语法解析

  • Promise构造函数的参数 是一个函数,称为执行器
  • Promis构造函数实例化对象时 会当即调用执行器函数(立刻执行 ,所以 Promise对象通常使用函数包裹)

执行器函数解析

参数

执行器函数接收两个参数,resolve和reject。这两个都是函数,由JS引擎提供 javascript

执行

执行器函数内一般会执行一些异步操做,一旦异步操做完成,能够经过判断,要么调用resolve函数将Promise的状态由pending改成fulfilled,或者调用reject将Promise的状态修改成rejected html

错误

若是在执行器函数内抛出一个错误,那么该promise的状态就会变化rejected,执行器函数的返回值将被忽略。 java

Promise的状态

Promise对象有三种状态promise

  • pending 初始状态
  • fulfilled  成功状态
  • rejected 失败状态

pending状态的Promise对象可能会变为fulfilled状态并传递一个值给相应的状态处理方法。也能够变为失败状态并传递失败信息。浏览器

属性

  1. Promise.length length属性,其值老是为1
  2. Promise.prototype 表示Promise构造函数的原型

方法(由Promise调用)

Promise.resolve(value)

返回一个给定值解析后的Promise对象。(将参数转化为Promise对象)。 异步

返回值规则

  • 若是value为基本类型的值,则返回一个resolved状态的Promise,并将value做为返回的Promise的第一个回调函数的参数。(做为成功回调函数的参数)
  • 若是value为Promise,则返回这个Promise。
  • 若是value为thenable对象,(定义了then方法的对象),返回的Promise会紧随这个对象,而且采用它的最终状态。(疑问)

注意

不要在解析为自身的thenable对象上调用Promise.resolve(),这将会致使无线递归。(有疑问)函数

Promise.reject(reason)

返回一个带有拒绝缘由参数的Promise对象ui

Promise.reject("Testing static reject").then(
  function(reason) {
  // 成功时的回调函数未被调用
}, function(reason) {
  // 失败时的回掉函数 执行了
  console.log(reason); // "Testing static reject"
});

复制代码

Promise.all(iterable)

Promise.race(iterable)

原型属性

原型属性是指Promise.prototype上的属性,即每一个实例的公有属性。spa

  • Promise.prototype.constructor  返回被建立的实例的构造函数,默认为Promise()

原型方法

Promise.prototype.then(onFulfilled,onRejected)

参数

最多须要两个参数,Promise状态变为成功时的回调函数以及状态变为失败时的回调函数。 prototype

参数省略的状况

若是忽略针对某个状态的回调函数参数,或者提供非函数参数,那么then方法将会丢失关于该状态的回调函数信息,可是并不会产生错误。
若是调用then方法的Promise状态发生变化,可是then方法中没有关于这种状态的回调函数,那么then方法将自动建立一个没有通过回调函数处理的新Promise对象,这么新的Promise的状态就是原来的Promise的终态。(仔细理解)

var p = new Promise((resolve, reject) => {
    resolve('foo')
})
// 'bar'不是函数,会在内部替换为 (x)=>x
p.then('bar').then((value)=>{
	console.log(value) //'foo'
})
复制代码

参数解析

  • onFulfilled 当Promise状态变成接受状态时,该参数做为回调函数被调用。该函数有一个参数,即接受的最终结果。
  • onRejected 当Promise变成拒绝状态,该参数做为回调函数被调用。该函数有一个参数,即拒绝的缘由。

返回值

返回值存在如下几种状况:

  • 返回一个值
  • 不返回值
  • 返回一个Promise
    • 返回一个完成状态的Promise
    • 返回一个拒绝状态的Promise
    • 返回pengding状态的Promise

具体分析以下:

  1. 若是then中的回调函数返回一个值,那么then中返回 的promise会变成接受状态,而且将返回的值做为接受状态的回调函数的的参数值。
// 实例化一个Promise对象
var p = new Promise((resolve,reject)=>{ resolve('foo')})
// 首先 resolve函数 能够向回调函数传递一个值,经过resolve(value)的方式
p.then((value)=>{
	return 'xhb' // then中的回调函数返回 return一个值
})
// 首先 咱们知道 then方法 会返回一个Promise对象
// 根据规则,若是在then中的回调函数中返回一个值, 会将整个then方法返回的promise的状态变为成功状态
// 而且 咱们在上一个promise return的值,会做为下一个promise的then方法中第一个回调函数(完成状态的
//的回调函数)的参数,便可以在完成状态的回调函数接受到这个值,咱们能够打印一下
p.then((value)=>{
	return 'xhb'
}).then(value => {
	console.log(value)
})

复制代码

在浏览器中运行以下:

  1. 若是then中回调函数没有返回值,那么then方法返回的Promise状态会变成接受状态,而且这个promise的第一个回调函数(成功状态的回调)会接受一个undefined的参数

具体分析以下:

// 实例化一个Promise
var p = new Promise((resolve,reject)=>{ resolve("foo")})

p.then((value)=>{
  console.log(value) // 打印参数 这里并无返回值 
  // 根据规则,then方法就会返回一个resolved状态的promise,而且接收一个值为undefinde的参数
}).then(
  function(value){
    // 接收一个值为undefined的参数
    console.log(value) // undefined
  }
)

复制代码

在浏览器中运行以下:

  1. 若是then方法中的回调函数抛出一个错误,那么then方法将返回一个rejected状态的Promise,而且抛出的错误将做为这个Promise的第二个回调函数(拒绝状态的回调函数)的参数。
  2. 返回一个resolved状态的Promise,若是then中的回调函数返回一个已是成功接受状态的Promise,那么then中返回的Promise也是成功状态,而且将那个Promise的接受状态的回调函数参数值做为then方法返回的Promise的接受状态的回调函数的参数(成功状态的回调函数的参数 会传递)

具体分析以下:

// 实例化一个Promise
var p = new Promise({(resolve,reject)=>{ resolve('foo')})
// 返回一个成功状态的Promise
// ? 调用构造函数 实例化Promise的时候,就已经执行了执行器函数,
p.then(()=>return new Promise((resolve)=>{ resolve('return PromiseValue')})
复制代码

在浏览器中运行

Promise.prototype.catch(onRejected)

catch方法返回一个Promise,而且处理拒绝的状况。它的行为与调用Promise.prototype.then()。

参数
  • OnReject   当Promise被rejected时,被调用的一个Funtion。该函数拥有一个参数:
    • reason rejection的缘由
    • 若是 onRejected抛出一个错误或返回一个自己失败的Promise,经过catch()返回的Promise被rejected,不然,它将显示为成功。

Promise.prototype.finally(onFinally)

finally()方法返回一个Promise。在Promise结束时,不管结果是fulfilled,或者是rejected,都会执行执行的回调函数。
这避免一样的语句须要在then方法和catch方法中各写一次。

建立Promise

Promise对象是由关键字new及其构造函数来建立的。
该构造函数会把一个叫作处理器的函数做为它的参数。
处理器函数接受两个函数resolve和reject做为它的参数。
当异步任务顺利完成且返回结果值的时候,会调用resolve函数。
而当异步任务失败且返回失败缘由时,会调用reject函数。

实例

//使用Promise 完成读取文件
const fs = require('fs')
// 实例化一个promise对象
const readFilePromise = function(fileName){
	return new Promise((resolve,reject)=>{
  	fs.readFile(fileName,'utf-8',(err,data)=>{
    	if(err) reject(err)
        resolve(data)
    })
    
  })
}
const p1 = readFilePromise('./index.html')
p1.then((data)=>{
    console.log(data)
}).catch(err=>{
    console.log(err)
})

复制代码
相关文章
相关标签/搜索