少小白学前端——promise()篇

Promise用于处理异步操作,解决回调地狱问题,提供链式调用。.then处理成功和失败,catch捕获异常。Promise.all等待所有Promise完成,any只需一个成功,finally无论结果如何都会执行,race返回首个完成的Promise。
摘要由CSDN通过智能技术生成

一、什么是promise,为何要用promise

Promise 对象用于表示一个异步操作的最终完成(或失败)及其结果值,是异步编程的一种解决方案。
通常,我们在写异步函数的时候,可以用一个回调函数来处理返回结果,例如:

function getData(callback) {
	setTimeout(() =>  {
		callback('hello')
	}, 1000)
}

getData(result => {
	console.log(result)  // hello
})

但是,如果返回结果需要用于二次加载,那么我们还需要嵌套一个回调函数,这样代码就复杂起来了,如果结果需要多次处理呢,这就不得不说Promise的优点:链式结构了,直接上代码:

const myPromise = new Promise((resolve, reject) => {
	setTimeout(() => {
		var result;  // 假设result为返回的结果
		if (result) {
          resolve('成功')
        } else {
          reject('失败')
        }
      }, 1000)
    });
    
myPromise
	.then((success) => {
    	console.log(1, success)
    }, (fail) => {
        console.log(2, fail)
    })
    .catch((error) => {
        console.log(3, error)
    })

上面,Promise()在创建时,需要接收一个函数作为参数,一旦Promise创建成功,这个函数会立即执行。它有两个参数,而且这两个参数也都是函数,resolve是在成功(或是解决问题)时执行,reject则是失败时执行。
不论成功或是失败,Promise都会返回一个结果,而这个结果就可以通过.then()方法获取。

二、Promise的链式结构

.then() 方法需要两个参数,第一个作为Promise状态成功时resolve的回调,第二个则是状态变为失败时reject的回调。
再看上边的函数,如果result成功获取,控制台则会输出“1 成功”,否则会输出“2 失败”。
那么catch是什么情况?
其实,then方法的第二个函数也可以不写,只处理成功状态,这样的话,如果失败,则会被catch捕捉,这时控制台才会输出“3 失败”。
那么,如果.then方法写了第二个参数,是不是就不用写.catch了呢?
.catch除了会捕获reject状态,在resolve处理结果的时候,如果发生意料之外的错误,也会被catch捕获,相当于 try {} catch (e) {} 方法。
除此之外,每一个 .then() 方法还会返回一个新生成的 promise 对象,这个对象可继续调用.then方法。

const myPromise = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('foo');
  }, 1000);
});
myPromise
  .then(handleResolvedA, handleRejectedA)
  .then(handleResolvedB, handleRejectedB)
  .then(handleResolvedC, handleRejectedC);

由于过早地处理变为reject状态的 promise 会对之后 promise 的链式调用造成影响,因此建议用下面的方法:

myPromise
  .then(handleResolvedA)
  .then(handleResolvedB)
  .then(handleResolvedC)
  .catch(handleRejectedAny);

三、Promise的其他方法

1. Promise.all()

Promise.all() 方法接收一个 promise 的 iterable 类型(Array,Map,Set)的输入,并且只返回一个Promise实例,这是什么情况呢,看定义不如上代码:

Promise.all([10, 18, 23, 25].map(number => {
      return new Promise((resolve, reject) => {
        if (number > 0) {
          resolve(`成功${number}`)
        } else {
          reject(`失败${number}`)
        }
      })
    })).then((r) => {
      console.log(1, r)
    }, (r) => {
      console.log(2, r)
    })

map过后,每个方法都返回一个Promise,当全部Promise执行完的时候,就会返回一个结果。此时,控制台的输出结果是:
在这里插入图片描述
这是都成功的情况,如果我们改一下条件,将number > 0 改为 number < 20, 会出现怎么结果呢?
在这里插入图片描述
这时,Promise.all会返回第一个失败的结果,不管其他Promise是否完成。

2. Promise.any()

与Promise.all()类似,当有一个满足条件的时候,就会变成resolve状态。
如果上边的例子变成Promise.any的话,成功时(number > 20):
在这里插入图片描述
失败时(number > 50):
在这里插入图片描述

3. finally()

在 promise 结束时,不论是成功(resolve)还是失败(reject),finally()方法都会执行,可以避免同样的语句需要在 then() 和 catch() 中各写一次的情况。

myPromise.finally(function() {
   // 返回状态为 (resolved 或 rejected)
});
4. race()

race()在Promise的迭代中,会返回第一个执行完的Promise的结果,不管是成功(resolve)还是失败(reject)。

const promise1 = new Promise((resolve, reject) => {
    setTimeout(resolve, 500, 'one');
});

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

Promise.race([promise1, promise2]).then((value) => {
    console.log(value);
});

在这个例子中,输出结果为“two”,因为它执行的快。即使将resolve改为reject也一样,只管返回结果的速度,不管成功或是失败。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值