Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

【JavaScript】Promise 基础 #23

Open
Tracked by #6
swiftwind0405 opened this issue Mar 5, 2020 · 0 comments
Open
Tracked by #6

【JavaScript】Promise 基础 #23

swiftwind0405 opened this issue Mar 5, 2020 · 0 comments

Comments

@swiftwind0405
Copy link
Owner

swiftwind0405 commented Mar 5, 2020

基础

Promise 必须为以下三种状态之一:等待态(Pending)、执行态(Fulfilled)和拒绝态(Rejected)。一旦 Promiseresolvereject,不能再迁移至其他任何状态(即状态 immutable)。

image

基本过程:

  1. 初始化 Promise 状态(pending
  2. 执行 then(..) 注册回调处理数组(then 方法可被同一个 promise 调用多次)
  3. 立即执行 Promise 中传入的 fn 函数,将 Promise 内部 resolvereject 函数作为参数传递给 fn ,按事件机制时机处理
  4. Promise 中要保证,then 方法传入的参数 onFulfilledonRejected,必须在 then 方法被调用的那一轮事件循环之后的新执行栈中执行。

Promise 最大的意义在于给予我们使用异步时丢失的 returnthrow 和栈。

Promise 中,返回任意一个非 promise 的值都会被包裹成 promise 对象,例如 return 2 会被包装为 return Promise.resolve(2)

方法

Promise.prototype.then()

Promise 实例具有 then 方法,即 then 方法是定义在原型对象 Promise.prototype 上的,作用是给 Promise 实例添加状态改变时的回调函数。then 方法的第一个参数是 Resolve 状态的回调函数,第二个是 Rejected(可选)状态的回调函数。

Promise.prototype.catch()

Promise.prototype.catch的方法是.then(null,rejection)的别名,用于指定发生错误的回调函数。

Promise.prototype.finally()

  • .finally() 方法不管 Promise 对象最后的状态如何都会执行
  • .finally() 方法的回调函数不接受任何的参数,也就是说在 .finally() 函数中是没法知道 Promise 最终的状态是 resolved 还是 rejected
  • 它最终返回的默认会是一个上一次的 Promise 对象值,不过如果抛出的是一个异常则返回异常的 Promise对象

Promise.all()

Promise.all(iterable) 方法返回一个 Promise 实例,此实例在 iterable 参数内所有的 promise 都“完成(resolved)”或参数中不包含 promise 时回调完成(resolve);如果参数中 promise 有一个失败(rejected),此实例回调失败(reject),失败原因的是第一个失败 promise 的结果。

Promise.race()

Promise.race(iterable) 方法返回一个 promise,一旦迭代器中的某个 promise 解决或拒绝,返回的 promise 就会解决或拒绝,而其余的 promise 虽然依旧在执行,但是其结果会被抛弃。

使用场景:可以用race给某个异步请求设置超时时间,并且在超时后执行相应的操作。

allrace 传入的数组中如果有会抛出异常的异步任务,那么只有最先抛出的错误会被捕获,并且是被 then 的第二个参数或者后面的 catch 捕获;但并不会影响数组中其它的异步任务的执行。

Promise.allSettled()

Promise.allSettled() 方法返回一个 promise,该 promise 在所有给定的 promise 已被解析或被拒绝后解析,并且每个对象都描述每个 promise 的结果。

Promise.resolve()

返回一个 fulfilledPromise 实例,或原始 Promise 实例。

  • 参数为空,返回一个状态为 fulfilledPromise 实例
  • 参数是一个跟 Promise 无关的值,返回一个状态为 fulfilledPromise 实例,同时 fulfilled 响应函数会得到喝过参数
  • 参数为 Promise 实例,则返回该实例,不做任何修改。
  • 参数为 thenable,立刻执行它的 .then()

Promise.reject()

返回一个 rejectedPromise 实例。

Promise.resolve() 大体类似,除了 Promise.reject() 不认 thenable

总结:

  • .then.catch 都会返回一个新的 Promise
  • catch 不管被连接到哪里,都能捕获上层未捕捉过的错误
  • Promise.then 或者 .catch 可以被调用多次, 但如果 Promise 内部的状态一经改变,并且有了一个值,那么后续每次调用 .then 或者 .catch 的时候都会直接拿到该值
  • .then 或者 .catchreturn 一个 error 对象并不会抛出错误,所以不会被后续的 .catch 捕获
  • .then.catch 返回的值不能是 promise 本身,否则会造成死循环
  • .then 或者 .catch 的参数期望是函数,传入非函数则会发生值透传
  • .then 方法是能接收两个参数的,第一个是处理成功的函数,第二个是处理失败的函数,再某些时候你可以认为 catch.then 第二个参数的简便写法
  • .finally 方法也是返回一个 Promise,他在 Promise 结束的时候,无论结果为 resolved 还是rejected,都会执行里面的回调函数

链式调用

Promise 能够链式调用的原理,即:promisethen/catch 方法执行后会也返回一个 promise

实现 Ajax

let getJSON=function(url){
    let promise=new Promise(function(){
        let client=new XMLHttpRequest()
        client.open('GET',url)
        client.onreadystatechange=hander
        cilent.responseType='json'
        client.setRequestHeader('Accept',"application/json")
        client.send()
        function hander(){
            if(this.readystate!=4){
                return
            }
            if(this.statues===200){
                resolve(this.response)
            }else{
                reject(new Error(this.stautsText))
            }
        }
    })
    return promise
}

//使用
getJSON('/xxx/xx.json').then((json)=>{
    console.log('contents'+json)
},(error)=>{
    console.log("请求出错"+error)
})

参考资料

@swiftwind0405 swiftwind0405 changed the title React-Hooks 【Day23】模块化 Mar 16, 2020
@swiftwind0405 swiftwind0405 changed the title 【Day23】模块化 【JavaScript】模块化 Apr 29, 2020
@swiftwind0405 swiftwind0405 changed the title 【JavaScript】模块化 【JavaScript】Promise May 23, 2020
@swiftwind0405 swiftwind0405 changed the title 【JavaScript】Promise 【JavaScript】Promise 基础 May 25, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant