Promise

本文深入探讨了JavaScript中Promise的使用方法,包括其构造函数、常见方法如all、race等,以及async/await语法糖如何简化异步编程。通过实例展示了如何处理异步操作,如数据下载和处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

promise

概念

  •     Promise是一个构造函数。
  •     该函数有一个函数参数
  •     函数参数有两个参数 resolve reject ,分别为成功与失败之后的回调函数。


用法


    var promise = new Promise(function(resolve,reject){
            ...
        })
 

  • 1.Promise.all()=>用于汇总多个promise的结果。
  • 2.Promise.race()
  • 3.Promise.reject(reason)
  • 4.Promise.resolve(value)
  • 5.Promise.prototype.catch(onRejected)
  • 6.Promise.prototype.then(onFulfilled, onRejected)
  • 7.Promise.prototype.finally(onFinally)

async

1.一个async函数可以包含一个await表达式,暂停异步函数的执行并等待传入Promise的解析,然后恢复async函数的执行并返回解析后的值。
eg:=>


function resolveAfter2Seconds(x) {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve(x);
    }, 2000);
  });
}


async function add1(x) {
  const a = await resolveAfter2Seconds(20);
  const b = await resolveAfter2Seconds(30);
  return x + a + b;
}

add1(10).then(v => {
  console.log(v);  // prints 60 after 4 seconds.
});


async function add2(x) {
  const p_a = resolveAfter2Seconds(20);
  const p_b = resolveAfter2Seconds(30);
  return x + await p_a + await p_b;
}

add2(10).then(v => {
  console.log(v);  // prints 60 after 2 seconds.
});
 

2.函数重写承诺链


function getProcessedData(url) {
  return downloadData(url) // returns a promise
    .catch(e => {
      return downloadFallbackData(url)  // returns a promise
    })
    .then(v => {
      return processDataInWorker(v); // returns a promise
    });
}
它可以用一个async函数重写,如下所示:

async function getProcessedData(url) {
  let v;
  try {
    v = await downloadData(url); 
  } catch(e) {
    v = await downloadFallbackData(url);
  }
  return processDataInWorker(v);
}
 

Promise.all()

用法:Promise.all(迭代)

迭代:一个可迭代的对象,如Array或者String.

返回值

 异步性

1.同步,当且仅当通过的迭代是空的时,Promise.all同步解析
2.异步,不然就要异步处理
  快速性
3.快速行为,如果任何元素被拒绝,则Promise.all被拒绝。

eg:1&2=>
```bash
var p = Promise.all([]); // will be immediately resolved
var p2 = Promise.all([1337, "hi"]); // non-promise values will be ignored, but the evaluation will be done asynchronously
console.log(p);
console.log(p2)
setTimeout(function(){
    console.log('the stack is now empty');
    console.log(p2);
});

// logs
// Promise { <state>: "fulfilled", <value>: Array[0] }
// Promise { <state>: "pending" }
// the stack is now empty
// Promise { <state>: "fulfilled", <value>: Array[2] }
```
eg:3=>
```bash
var p1 = new Promise((resolve, reject) => { 
  setTimeout(resolve, 1000, 'one'); 
}); 
var p2 = new Promise((resolve, reject) => { 
  setTimeout(resolve, 2000, 'two'); 
});
var p3 = new Promise((resolve, reject) => {
  setTimeout(resolve, 3000, 'three');
});
var p4 = new Promise((resolve, reject) => {
  setTimeout(resolve, 4000, 'four');
});
var p5 = new Promise((resolve, reject) => {
  reject('reject');
});

Promise.all([p1, p2, p3, p4, p5]).then(values => { 
  console.log(values);
}, reason => {
  console.log(reason)
});

//From console:
//"reject"

//You can also use .catch
Promise.all([p1, p2, p3, p4, p5]).then(values => { 
  console.log(values);
}).catch(reason => { 
  console.log(reason)
});

//From console: 
//"reject"
 

Promise.race()

用法 Promise.race(迭代)

1.如果通过的迭代是空的,则返回的promise将永远等待。
2.如果迭代包含一个或多个非承诺值和/或已经解决/拒绝的承诺,Promise.race 则将解析为在迭代中找到的这些值中的第一个。
3.也有异步性


eg:2=>

var foreverPendingPromise = Promise.race([]);
var alreadyResolvedProm = Promise.resolve(666);

var arr = [foreverPendingPromise, alreadyResolvedProm, "non-Promise value"];
var arr2 = [foreverPendingPromise, "non-Promise value", Promise.resolve(666)];
var p = Promise.race(arr);
var p2 = Promise.race(arr2);

console.log(p);
console.log(p2);
setTimeout(function(){
    console.log('the stack is now empty');
    console.log(p);
    console.log(p2);
});// logs, in order:
// Promise { <state>: "pending" } 
// Promise { <state>: "pending" } 
// the stack is now empty
// Promise { <state>: "fulfilled", <value>: 666 }
// Promise { <state>: "fulfilled", <value>: "non-Promise value" }

 

var p1 = new Promise(function(resolve, reject) { 
    setTimeout(resolve, 500, 'one'); 
});
var p2 = new Promise(function(resolve, reject) { 
    setTimeout(resolve, 100, 'two'); 
});

Promise.race([p1, p2]).then(function(value) {
  console.log(value); // "two"
  // Both resolve, but p2 is faster
});


 

### Promise 的工作原理 Promise 是 JavaScript 中处理异步操作的一种核心机制,其设计基于状态管理和回调注册的思想。Promise 本质上是一个对象,表示一个异步操作的最终完成(或失败)及其结果值。Promise 有三种状态:`pending`(等待态)、`fulfilled`(成功态)和 `rejected`(失败态)。一旦状态发生变化,就不会再变,这种状态的不可逆性是 Promise 的核心特性之一[^2]。 在内部实现上,Promise 采用了发布-订阅模式。当异步操作尚未完成时,Promise 处于 `pending` 状态,此时可以通过 `then` 方法注册回调函数,等待状态变为 `fulfilled` 或 `rejected` 时触发相应的回调。这种机制类似于事件监听,但更结构化和可控,避免了传统回调地狱的问题[^3]。 Promise 的执行是同步的,构造一个 Promise 实例时,其传入的执行函数会立即执行,但其内部的异步操作(如 setTimeout)会进入事件循环的微任务队列,等待当前同步任务执行完毕后才被处理。这使得 Promise 具有良好的调度顺序[^1]。 ### Promise 的使用方法 #### 基本结构 ```javascript const promise = new Promise((resolve, reject) => { // 异步操作 if (/* 成功 */) { resolve(value); // 成功状态 } else { reject(error); // 失败状态 } }); ``` #### 链式调用 Promise 支持链式调用,通过 `then` 方法可以依次处理异步操作的结果,每个 `then` 返回一个新的 Promise,从而实现异步流程控制: ```javascript promise .then(value => { console.log('Success:', value); return value + 1; }) .then(newValue => { console.log('New value:', newValue); }) .catch(error => { console.error('Error:', error); }); ``` #### 错误处理 Promise 的错误处理通过 `catch` 方法进行,它可以捕获链式调用中任意一个环节抛出的错误。建议始终使用 `catch` 来统一处理错误,以避免未捕获的 Promise rejection 导致程序崩溃。 #### 静态方法 Promise 构造函数自身提供了一些静态方法,用于处理多个 Promise 的组合和控制: - `Promise.resolve(value)`:返回一个以给定值解析的 Promise。 - `Promise.reject(reason)`:返回一个以给定原因拒绝的 Promise。 - `Promise.all(iterable)`:接收一个 Promise 数组,全部成功才成功,有一个失败就立即失败。 - `Promise.race(iterable)`:接收一个 Promise 数组,只要有一个 Promise 状态改变,就触发后续操作。 ### 常见问题与注意事项 - **避免未处理的 rejection**:如果一个 Promise 被拒绝但没有对应的 `catch` 捕获,可能导致程序运行异常。应始终为 Promise 链添加错误处理。 - **链式调用中的返回值**:在 `then` 中返回的值会作为下一个 `then` 的输入。若返回的是另一个 Promise,则会等待该 Promise 解析后再继续执行链式流程。 - **异步顺序问题**:由于 Promise 使用微任务队列,其回调执行顺序优先于 `setTimeout` 等宏任务,但在多个 Promise 回调之间仍然遵循注册顺序。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值