32.Promise

4/16/2023 js

# 1.Promise说明

Promise对象用于表示一个异步操作的最终完成(或失败)及其结果【抽象表达:Promise 是JS中进行异步编程的新的解决方案(旧的是谁?=> 纯回调的形式)】
异步方法并不会立即返回最终的值,而是会返回一个 promise,以便在未来某个时候把值交给使用者。
一个Promise必然处于以下几种状态之一:

  • 待定(pending):初始状态,既没有被兑现,也没有被拒绝。(什么也不调用,或者返回一些值,promise对象就是等待状态)
  • 已兑现(fulfilled):意味着操作成功完成。 (调用resolve,promise对象就是成功状态)
  • 已拒绝(rejected):意味着操作失败。(调用reject,promise对象就是失败状态。抛异常throw,也是失败状态)
    因为Promise.prototype.then和Promise.prototype.catch方法返回的是promise,所以它们可以被链式调用。

# 状态改变

  • pending -> fulfilled
  • pending -> rejected 且一个Promise对象只能改变一次,无论变成成功还是失败,都会有一个结果数据,成功的结果数据一般称为value,失败的结果数据一般称为reason。
// new Promise(构造函数),构造函数有两个参数:resolve, reject
const fetchData = new Promise((resolve, reject) => {
  // 使用 Ajax 请求数据
  ajax('http://example.com/data', (response) => {
    if (response.status === 'success') {
      resolve(response.data);
    } else {
      reject(new Error('Failed to fetch data'));
    }
  });
});

// 处理数据
fetchData.then((data) => {
  // 成功获取数据
  console.log(data);
}).catch((error) => {
  // 获取数据失败
  console.error(error);
});


// Promise.resolve(value):返回一个已经 resolved(成功)的 Promise 对象
return Promise.resolve('操作成功')

// Promise.reject(reason):返回一个已经 rejected(失败)的 Promise 对象
return Promise.reject(new Error('操作失败'));


// 调用函数a,console并不会执行。因为await的promise对象并没有执行调用resolve,此时promise处于pending状态,不会向下执行
const a = async() => {
    const res = await new Promise((resolve) => {})
    console.log('res', res)
}
a()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

# 2.Promise.all()

Promise.all()等待所有都完成(或者第一个失败)
返回值:

  • 如果传入的参数是一个空的可迭代对象,则返回一个已完成状态的Promise
  • 如果传入的参数不包含任何promise,则返回一个异步完成Promise
  • 其他情况下返回一个处理中(pending)的Promise。这个返回的promise之后会在所有的promise都完成或有一个promise失败时异步地变为完成或失败
var p1 = Promise.resolve(3);
var p2 = 1337;
var p3 = new Promise((resolve, reject) => {
  setTimeout(resolve, 100, 'foo');
});
var p4 = Promise.reject(4)

const test = Promise.all([p1, p2, p3, p4]).then(values => {
  console.log('values', values); // 此处不打印
});
// Promise {<rejected>: 4}
1
2
3
4
5
6
7
8
9
10
11

# 3.Promise.race()

包含n个promise的数组,返回一个新的promise, 第一个完成的promise的结果状态就是最终的结果状态

// 产生一个成功值为 1 的 Promise 对象
const p1 = new Promise((resolve, reject) => {
  resolve(1)
})

// 产生一个成功值为 2 的 Promise 对象
const p2 = Promise.resolve(2)
// 产生一个失败值为 3 的 Promise 对象
const p3 = Promise.reject(3)

// p1.then(value => console.log(value))
// p2.then(value => console.log(value))
// p3.catch(reason => console.error(reason))

const pAll = Promise.all([p1, p2, p3])
pAll.then(values => {
  console.log('all onResolved()', values) 
}, reason => {
  console.log('all onRejected()', reason) // all onRejected() 3
})

const race = Promise.race([p1, p2, p3])
race.then(value => {
  console.log('all onResolved()', value) // all onResolved() 1
}, reason => {
  console.log('all onRejected()', reason) 
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

# 4.promise.then()

promise.then()返回的新promise的结果状态由then()指定的回调函数执行的结果决定

  • 如果抛出异常, 新promise变为rejected, reason为抛出的异常
  • 如果返回的是非promise的任意值, 新promise变为resolved, value为返回的值
  • 如果返回的是另一个新promise, 此promise的结果就会成为新promise的结果
new Promise((resolve, reject) => {
  resolve(1)
}).then(
  value => {
    console.log('onResolved1()', value); 
    // return 1.1 或 
    return Promise.resolve(1.1)
    // return Promise.reject(1.1)
    // throw 1.1
  },
  reason => { 
    console.log('onRejected1()', reason);
  }
).then(
  value => { console.log('onResolved2()', value); }, 
  reason => { console.log('onRejected2()', reason) } 
)
// onResolved1() 1
// onResolved2() 1.1​
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

# 5.回调地狱

回调地狱:回调函数嵌套调用,外部回调函数异步执行的结果是嵌套的回掉执行条件,代码是水平向右扩展

doSomething(function(result) {
  doSomethingElse(result, function(newResult) {
    doThirdThing(newResult, function(finalResult) {
      console.log('Got the final result: ' + finalResult)
    }, failureCallback)
  }, failureCallback)
}
// 回调地狱的缺点:不便阅读,不便于异常处理
1
2
3
4
5
6
7
8

解决方案:Promise 链式调用,代码水平向下扩展

doSomething().then(function(result) {
  return doSomethingElse(result)
})
.then(function(newResult) {
  return doThirdThing(newResult)
})
.then(function(finalResult) {
  console.log('Got the final result: ' + finalResult)
})
.catch(failureCallback)
1
2
3
4
5
6
7
8
9
10

终极解决方案:async/await,用同步的写法处理异步的操作

async function request() {
  try {
    const result = await doSomething()
    const newResult = await doSomethingElse(result)
    const finalResult = await doThirdThing(newResult)
    console.log('Got the final result: ' + finalResult)
  } catch (error) {
    failureCallback(error)
  }
}
1
2
3
4
5
6
7
8
9
10
最近更新时间: 5/7/2023, 2:48:39 PM
강남역 4번 출구
Plastic / Fallin` Dild