Promise简介

在 JavaScript 中,Promise 是一种强大的异步编程工具,用于处理异步操作。

1. 语法简介

Promise 是 JavaScript 中用于处理异步操作的对象,它提供了更清晰和可维护的方式来管理异步任务。Promise 有三种状态:未完成(pending)、已完成(fulfilled)、已拒绝(rejected)。以下是 Promise 的基本语法:

  1. 创建一个 Promise 对象:

    const myPromise = new Promise((resolve, reject) => {
      // 异步操作
      // 如果操作成功,调用 resolve
      // 如果操作失败,调用 reject
    });
    

    在创建 Promise 时,传递一个带有两个参数的函数,通常称为执行函数。这个执行函数接受两个参数:resolvereject,它们分别用于将 Promise 标记为已完成或已拒绝。

  2. 处理 Promise 的结果:

    使用 then 方法来处理 Promise 的结果,它接受两个回调函数作为参数,第一个回调用于处理成功的情况,第二个回调用于处理失败的情况。

    myPromise.then(
      function (result) {
        // 处理成功的情况
      },
      function (error) {
        // 处理失败的情况
      }
    );
    

    你也可以只提供处理成功的回调,或只提供处理失败的回调,取决于你的需求。

2. Promise 错误处理

首先,让我们看一下如何在 Promise 中处理错误。一个常见的错误处理方式是在 Promise 的 then 方法中传递两个回调函数,一个用于处理成功的情况,另一个用于处理错误的情况。

const p1 = new Promise((resolve, reject) => {
  foo.bar(); // 试图调用一个未定义的函数
  resolve("hello");
});

p1.then(
  function fulfilled() {
    // 永远不会到达这里
  },
  function rejected(err) {
    console.log(err); // 输出:ReferenceError: foo is not defined
  }
);

在上面的代码中,foo.bar() 会导致一个 ReferenceError,并且在 p1rejected 处理函数中捕获了这个错误。这是 Promise 错误处理的典型方式。

然而,有时候我们可能会遇到不应该执行错误处理函数的情况。例如,下面的代码中的 p3 是一个自定义的 Promise 对象,它的 then 方法会立即执行并触发一个错误:

var p3 = {
  then: function (cb, errcb) {
    cb(42);
    errcb("嚯哈哈哈哈哈,不应该执行的");
  },
};

p3.then(
  function fulfilled(val) {
    console.log(val); // 输出:42
  },
  function rejected(err) {
    // 不应该运行!
    // console.log(err); // 输出:嚯哈哈哈哈哈,不应该执行的
  }
);

在这种情况下,错误处理函数也被调用了,尽管我们不希望它执行。为了解决这个问题,我们可以使用 Promise.resolve(..) 来包装 p3,这将确保只有真正的 Promise 对象才会执行错误处理函数:

Promise.resolve(p3).then(
  function fulfilled(val) {
    console.log(val); // 输出:42
  },
  function rejected(err) {
    console.log(err); // 永远不会到达这里
  }
);

如果在 fullfilled函数中出现错误,同级的 rejected 是不会捕获的,同级的捕获,只会捕获上一个链出现的错误。

var p = Promise.resolve( 42 ); 
p.then( 
 function fulfilled(msg){ 
 // 数字没有string函数,所以会抛出错误
     console.log( msg.toLowerCase() ); 
 }, 
 function rejected(err){ 
 // 永远不会到达这里
 } 
);

3. 链式调用

Promise 还允许我们构建链式调用,以更清晰地表示和管理异步操作的顺序。在链式调用中,每个 then 方法返回一个新的 Promise,允许我们继续添加操作。

var p4 = Promise.resolve(23);
p4.then(function (v) {
  console.log(v); // 输出:23
  return v * 2;
})
  .then(function (v) {
    console.log(v); // 输出:46
  });

在上面的代码中,我们首先创建一个解决值为 23 的 Promise,然后通过 then 方法添加了两个操作,分别将值乘以 2并打印结果。

有时候,我们需要在链式调用中进行异步操作,例如使用 setTimeout。在这种情况下,我们可以返回一个新的 Promise,以便在异步操作完成后继续链式调用:

var p5 = Promise.resolve(24);

p5.then((res) => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(res * 2);
    }, 3000);
  });
}).then(res => {
  console.log(res); // 3秒后输出:48
});

在上面的示例中,我们返回了一个新的 Promise,它在 setTimeout 完成后解决,然后我们继续链式调用并输出结果。

你可能感兴趣的:(JS高级,javascript,前端,js,ecmascript)