promise-进阶

72 阅读7分钟

一、promise.then的返回值

示例1:

const p = new Promise((resolve, reject) => {
    resolve('success')
})
const res1 = p.then(res => {
    console.log(res)  // success
})
console.log(res1) // 返回一个promise对象
  • res1的返回值:
  • image.png

示例2:

   const p = new Promise((resolve, reject) => {
    resolve('success')
})
const res1 = p.then(res => {
     return 'second success'
}).then(res => {
     console.log(res) // second success
})
  • 如果p.then中回调函数,返回了一个非promise的值,新的promise的将使用这个值作为成功的结果.

示例3:

  const p = new Promise((resolve, reject) => {
    resolve('success')
})
const res1 = p.then(res => {
     return new Promise((resolve,reject) => {reject(1)})
})
console.log(res1) // 返回一个promise对象
  • 返回值:
  • image.png
  • 如果回调函数本身返回了一个promise对象,则then方法调用后返回的新promise,与该promise对象采用相同的成功结果或失败原因

总结:

  1. then的回调中没有return ,那么promise成功的结果为undefined
  2. then中return了一个非promise对象,新promise以该值作为成功的结果
  3. then中return了一个promise对象,新promise 成功或失败与它相同

二、promise.then的第二个参数

  • promise.then() 可以接收两个函数作为参数。
 const p = new Promise((resolve, reject) => {
            setTimeout(() => {
                if (Math.random() > 0.5) {
                    resolve('success')
                } else {
                    reject('failed')
                }
            }, 1000)
        })
        
         p.then((res) => {
            console.log(res)
        }, (err) => {
            console.log(err)
        })
  • 第一个函数是promise状态为fulfilled时调用
  • 第二个回调函数是promise对象为reject时调用,与 .catch 一样。

三、Promise.resolve()

  • Promise.resolve() 是一个静态方法,用于创建一个已解决(resolved)的 Promise 对象。它接受一个参数作为 Promise 对象的解决值,并返回一个立即解决的 Promise 对象。

基本语法:

Promise.resolve(value);
  • 其中,value 是作为解决值的参数。可以是任何 JavaScript 的值,包括普通的值、对象、数组、甚至是另一个 Promise 对象。
  • 当调用 Promise.resolve(value) 时,它会返回一个 Promise 对象,该对象处于已解决状态,并将传递的值作为解决值。如果传递的值本身就是 Promise 对象,那么它会直接返回该 Promise 对象而不进行任何改变。

示例:

Promise.resolve(42).then(value => {
  console.log(value); // 输出: 42
});

const obj = { name: 'John' };
Promise.resolve(obj).then(value => {
  console.log(value); // 输出: { name: 'John' }
});

const arr = [1, 2, 3];
Promise.resolve(arr).then(value => {
  console.log(value); // 输出: [1, 2, 3]
});

const existingPromise = new Promise((resolve) => {
  setTimeout(() => {
    resolve('Resolved Promise');
  }, 1000);
});

Promise.resolve(existingPromise).then(value => {
  console.log(value); // 输出: Resolved Promise
});

  • Promise.resolve() 是一个便捷的方法,用于创建已解决的 Promise 对象,并提供了一种简洁的方式来处理已知的值或转换其他类型的对象为 Promise 对象。
  • Promise.resolve(1) 等价于 new Promise(resolve => resolve(1))

四、Promise.reject()

  • Promise.reject() 是一个静态方法,用于创建一个已拒绝(rejected)的 Promise 对象。它接受一个参数作为 Promise 对象的拒绝原因,并返回一个立即拒绝的 Promise 对象。

基本语法:

Promise.reject(reason);
  • 其中,reason 是作为拒绝原因的参数。可以是任何 JavaScript 的值,通常是一个 Error 对象或一个描述错误的字符串。当调用 Promise.reject(reason) 时,它会返回一个 Promise 对象,该对象处于已拒绝状态,并将传递的值作为拒绝原因。
  • 当调用 Promise.reject(reason) 时,它会返回一个 Promise 对象,该对象处于已拒绝状态,并将传递的值作为拒绝原因。

示例:

Promise.reject(new Error('Something went wrong')).catch(error => {
  console.log(error.message); // 输出: Something went wrong
});

  • 需要注意的是,与 Promise.resolve() 不同,Promise.reject() 创建的 Promise 对象始终是已拒绝的状态,无法被后续的 then() 方法处理,除非显式地使用 catch()finally() 来处理拒绝原因。
  • Promise.reject('出错了') 等同于 new Promise((resolve, reject) => reject('出错了'))

五、promise.all()

  • Promise.all() 是一个静态方法,用于将多个 Promise 对象包装成一个新的 Promise 对象,并在所有 Promise 对象都解决(resolved)时才解决,或者在任何一个 Promise 对象被拒绝(rejected)时进行拒绝。

基本语法:

const p = Promise.all([p1, p2, p3])
  • Promise.all接收一个promise数组或其他(用数组做示例)作为参数,返回一个新的promise对象。
  • 最后p的状态,由p1,p2,p3决定
  • 分两种情况
  1. 当p1,p2,p3都为fulfilled状态时,p的状态才会变成fulfilled(成功态、完成态)
  • p1,p2,p3的返回值,会挨个(按顺序)的组成一个新的数组,作为p的结果
  1. 只要p1, p2, p3 有一个被rejected了,失败了,p的状态就会变成rejected,
  • 第一个被rejected的promise的值(失败的原因),会作为p的结果

示例:

const promise1 = Promise.resolve(1);
const promise2 = Promise.resolve(2);
const promise3 = Promise.resolve(3);

Promise.all([promise1, promise2, promise3]).then(values => {
  console.log(values); // 输出: [1, 2, 3]
});

const promise4 = new Promise((resolve, reject) => {
  setTimeout(() => {
    reject(new Error('Rejected Promise'));
  }, 1000);
});

Promise.all([promise1, promise2, promise4]).catch(error => {
  console.log(error.message); // 输出: Rejected Promise
});

  • 需要注意的是,传入 Promise.all() 的可迭代对象中的元素可以是任何类型的值,不仅限于 Promise 对象。在这种情况下,这些值将被包装成已解决的 Promise 对象。只有当所有的 Promise 对象都解决时,或者其中一个被拒绝时,Promise.all() 才会返回。

六、promise.race()

  • Promise.race() 是一个静态方法,用于将多个 Promise 对象包装成一个新的 Promise 对象,并在其中任何一个 Promise 对象解决(resolve)或拒绝(reject)时,立即解决或拒绝。

基本语法:

const p = Promise.race([p1, p2, p3])
  • 只要p1, p2, p3之中 有一个实例率先改变状态,p的状态就跟着改变
  • race返回一个promise,它可以是完成态(成功态fulfilled),也可以是失败(rejected)
  • race竞赛,只认第一名

示例:

const promise1 = new Promise(resolve => setTimeout(resolve, 1000, 'Promise 1 resolved'));
const promise2 = new Promise(resolve => setTimeout(resolve, 2000, 'Promise 2 resolved'));
const promise3 = new Promise((resolve, reject) => setTimeout(reject, 1500, 'Promise 3 rejected'));

Promise.race([promise1, promise2, promise3]).then(result => {
  console.log(result); // 输出: Promise 1 resolved
}).catch(error => {
  console.log(error); // 不会被执行
});

  • 在上述示例中,我们创建了三个 Promise 对象,每个对象在不同的延迟时间后解决或拒绝。然后,我们将这三个 Promise 对象作为参数传递给 Promise.race() 方法。由于第一个 Promise 对象在 1 秒后解决,因此新的 Promise 对象也会在 1 秒后解决,并将第一个 Promise 对象的解决值作为自己的解决值输出到控制台。
  • 需要注意的是,如果传入 Promise.race() 的可迭代对象为空,或者没有一个 Promise 对象解决或拒绝,那么返回的 Promise 对象将永远处于挂起状态,不会解决或拒绝。

七、Promise.allSettled()

  • Promise.allSettled() 是一个静态方法,用于将多个 Promise 对象包装成一个新的 Promise 对象,并在所有的 Promise 对象都解决或拒绝后进行解决。

基本语法:

    Promise.allSettled([p1,p2,p3]);
  • 接收一个Promise数组,在所有promise对象都已经fulfilled或rejected后,返回一个返回每个promise结果的对象数组.

  • 每个对象有三个属性

    1. status => promsie的状态: fulfilled / rejected
    2. value =>成功的结果,如果rejected,undfined\
    3. reason =>失败的原因,如果fulfilled,undefined
  • 等待所有的结果都有了之后才返回.then的结果

示例:

const promise1 = Promise.resolve(1);
const promise2 = Promise.reject('Error');
const promise3 = new Promise(resolve => setTimeout(resolve, 1000, 'Delayed'));

Promise.allSettled([promise1, promise2, promise3]).then(results => {
  console.log(results);
});

  • 需要注意的是,Promise.allSettled() 方法返回的 Promise 对象总是解决的,即使传入的可迭代对象为空。此外,它会等待所有的 Promise 对象都解决或拒绝后才进行解决,并返回一个包含所有解决状态和解决值或拒绝原因的数组。

八、 Promise.any()

  • 等待第一个promise是成功的状态
  • Promise.any() 是一个静态方法,用于将多个 Promise 对象包装成一个新的 Promise 对象,并在其中任何一个 Promise 对象解决后进行解决

基本语法:

Promise.any(iterable);
  • 当调用 Promise.any(iterable) 时,它将返回一个新的 Promise 对象。这个新的 Promise 对象将与传入的 Promise 对象中最先解决的对象的状态相同,并将该对象的解决值作为自己的解决值传递。
  • 需要注意的是,与 Promise.all()Promise.allSettled() 不同,Promise.any() 不会等待所有的 Promise 对象都解决或拒绝。它只要有一个 Promise 对象解决,就会立即解决,忽略其他的 Promise 对象
  • 如果传入的所有 Promise 对象都被拒绝,则返回的 Promise 对象将被拒绝,并将一个 AggregateError 对象作为拒绝原因,其中包含了所有的拒绝原因。

示例:

const promise1 = new Promise(resolve => setTimeout(resolve, 2000, 'Promise 1 resolved'));
const promise2 = Promise.reject('Error 1');
const promise3 = new Promise(resolve => setTimeout(resolve, 1000, 'Promise 3 resolved'));

Promise.any([promise1, promise2, promise3]).then(result => {
  console.log(result); // 输出: Promise 3 resolved
}).catch(errors => {
  console.log(errors); // 不会被执行
});

  • 在上述示例中,我们创建了三个 Promise 对象,其中一个解决的、一个拒绝的和一个延迟解决的。然后,我们将这三个 Promise 对象作为参数传递给 Promise.any() 方法。由于第三个 Promise 对象最先解决,所以新的 Promise 对象也会立即解决,并将第三个 Promise 对象的解决值作为自己的解决值输出到控制台。