promise 详解

Promise

作用:主要是来解决Ajax的异步问题

传统方式:回调函数来解决异步问题,类似如下问题

ajax(url, {
    // 成功后回调
    ajax(url, {
        // 成功之后再回调
        ajax(url, {
            // 成功之后再回调
        })
    })
})

注意:一般情况下,如果请求成功,执行某个函数,看着比较混乱,一个回调还比较容易分清,如果是多个回调的话,代码易读性可想而知

Promise 两个特点

1、对象的状态不受外界影响。Promise 对象代表一个异步操作,有三种状态:

  • pending: 初始状态,不是成功或失败状态。
  • fulfilled: 意味着操作成功完成。
  • rejected: 意味着操作失败。

2、一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise 对象的状态改变,只有两种可能:从 Pending 变为 Resolved 和从 Pending 变为 Rejected。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果。就算改变已经发生了,你再对 Promise 对象添加回调函数,也会立即得到这个结果。这与事件(Event)完全不同,事件的特点是,如果你错过了它,再去监听,是得不到结果的。

优缺点

优点: 有了 Promise 对象,就可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数。此外,Promise 对象提供统一的接口,使得控制异步操作更加容易。

缺点: Promise 也有一些缺点。首先,无法取消 Promise,一旦新建它就会立即执行,无法中途取消。其次,如果不设置回调函数,Promise 内部抛出的错误,不会反应到外部。第三,当处于 Pending 状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)。

 

 

如何使用

1. 如何创建一个 promise,参数详解

let promise = new Promise(function(resolve, reject) {
    //当异步代码执行成功时,我们才会调用resolve(...), 当异步代码失败时就会调用reject(...)
    //在本例中,我们使用setTimeout(...)来模拟异步代码,实际编码时可能是XHR请求或是HTML5的一些API方法.
    setTimeout(function(){
        resolve("成功!"); //代码正常执行!
    }, 250);
});

方法一:
promise.then(success, fail)
// success 请求成功执行的内容
// fail 请求失败执行的内容

Eg: 
promise.then(function(data){
    //data的值是上面调用resolve(...)方法传入的值.
    //data参数不一定非要是字符串类型,这里只是举个例子
    console.log(data)
}, fail)

方法二:
promise.then(res=>{}).catch(err=>{})
// then 请求成功后执行内容
// catch 请求失败后执行内容

// 上边的这两种都可以使用,不过后者用的较为普遍

2. promise 简单使用

let a = 'hello'
let promise = new Promise(function(resolve, reject) {
    if (a === 'hello') {
        resolve('success')
    } else {
        reject('error')
    }
});

// 方法一
promise.then(res => {
    console.log(res)  // 如果 a === 'hello' 也就是 resolve 的情况下,就会打印 'success'
},err => {
    console.log(err) // 如果 a !== 'hello' 也就是 reject 的情况下就会打印 'error'
})

// 方法二
promise.then(res => {
    console.log(res)  // resolve 的情况下,就会走到这里
}).catch(err => {
    console.log(err) // reject 的情况下,会捕获到错误内容
})

3. promise.resolve() 和 promise.reject()

Promise.resolve('a') 将括号中的内容,转为一个promise 对象,并且是resolve (成功) 状态
// 等价于
new Promise(resolve => {
    resolve('a')
})

Promise.reject('a') 将括号中的内容,转为一个promise 对象,并且是reject (失败) 状态
// 等价于
new Promise(reject => {
    resolve('a')
})

 4. promise.all()

概念:Promise.all(ajax1, ajax2, ajax3) 方法返回一个 Promise 实例

此实例在参数内所有的 promise 都 请求成功(resolve) 或参数中不包含 promise 时回调完成(resolve)

如果参数中  promise 有一个失败(rejected),此实例回调失败(reject),失败原因会返回第一个失败 promise 的结果。

自我理解:

let promise = promise.all(ajax1, ajax2, ajax3) 

promise 相当于把ajax1, ajax2, ajax3打包,返回一个 promise 对象,只有三个全部成功时,promise 才会返回成功状态

如果其中一个请求失败了,promise 会直接返回失败,失败内容就为第一个请求失败的返回内容

var promise1 = Promise.resolve(3);
var promise2 = 42;
var promise3 = new Promise(function(resolve, reject) {
  setTimeout(resolve, 100, 'foo');
});

Promise.all([promise1, promise2, promise3]).then(function(values) {
  console.log(values);
});
// expected output: Array [3, 42, "foo"]

5. promise.race()

Promise.race(iterable) 方法返回一个 promise,一旦迭代器中的某个promise解决或拒绝,返回的 promise就会解决或拒绝。

自我理解:参数中可传入多个promise,只要其中一个完成(resolve, reject都算),直接返回

var promise1 = new Promise(function(resolve, reject) {
    setTimeout(resolve, 200, 'one');
});

var promise2 = new Promise(function(resolve, reject) {
    setTimeout(resolve, 100, 'two');
});

Promise.race([promise1, promise2]).then(function(value) {
  console.log(value);
  // 虽然两个都返回resolve的结果,但是promise2 返回的更快一些,所以输出的是promise2 的内容
});

6: 真实场景模拟

var promise1 = new Promise(function(resolve, reject) {
    $.ajax({
    type: 'POST/GET',
    url: '/jhbar/bar?appkey=key', // 随便写的url,
    success:function(data){
        resolve(data)
    }
    error:function(data){  
        reject(data)
	}
});

var promise2 = new Promise(function(resolve, reject) {
    $.ajax({
    type: 'POST/GET',
    url: '/jhbar/bar?appkey=key', // 随便写的url,
    success:function(data){
        resolve(data)
    }
    error:function(data){  
        reject(data)
	}
});

Promise.all([promise1, promise2]).then(function(value) {
    // 当所有的都请求成功了 就会走这里
    // 此时两个的数据都拿到了,但是只有一个value,所以需要解构一下
    let [data1, data2] = value
    // data1就是promise1 中返回的数据
    // data2就是promise2 中返回的数据
}).catch(function(err) {
    // 当其中一个 reject ,就会走这里 , 输出的错误原因是第一个被拒绝的原因
    console.log(err)
})

本文是个人的理解和总结,如有不妥,请赐教

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值