Promise的常见问题

178 阅读2分钟

温习Promise基础可以看看这篇文章:Promise从入门到精通,小白必看

Promise 的几个关键问题

1.改变 promise状态的三种方式

<script>
    let p = new Promise((resolve, reject) => {
        //1. resolve 函数状态会由pending变为resolved
        // resolve('ok'); //Promise {<fulfilled>: "ok"}
        //2. reject 函数
        // reject("error");//Promise {<rejected>: "error"}
        //3. 抛出错误
        throw '出问题了';//Promise {<rejected>: "出问题了"}
    });
    console.log(p);
</script>

2.一个 promise 指定多个成功/失败回调函数,都会调用吗?

当 promise 改变为对应状态时都会调用。

<script>
    let p = new Promise((resolve, reject) => {
        resolve('OK');//状态改变(e.g.:pending变成resolved)才会执行回调p.then
    });
    p.then(value => {///指定回调 - 1
        console.log(value);
    });
    p.then(value => {//指定回调 - 2
        alert(value);
    });
</script>

3.改变promise状态和指定回调函数谁先谁后?

都有可能,常规是先指定回调再改变状态,但也可以先改状态再指定回调. 如何先改状态再指定回调? (1)在执行器中直接调用 resolve()/reject() (2)延迟更长时间才调用 then() 什么时候才能得到数据? ①如果先指定的回调, 那当状态发生改变时, 回调函数就会调用, 得到数据 ②如果先改变的状态, 那当指定回调时, 回调函数就会调用, 得到数据

let p = new Promise((resolve, reject) => {
  setTimeout(() => {
      resolve('OK');
  }, 1000); // 有异步就先指定回调,否则先改变状态
});

p.then(value => {//回调
  console.log(value);
})

4.promise.then()返回的新promise的结果状态由什么决定?

由then()指定的回调函数执行的结果决定。

<script>
    let p = new Promise((resolve, reject) => {
        resolve('ok');
    });
    //执行 then 方法
    let result = p.then(value => {
        //console.log(value);
        //1. 抛出错误,新promise变为rejected, reason为抛出的异常
        //throw '出了问题';
        //2. 返回结果是非 Promise 类型的对象,新promise变为resolved, value为返回的值
        // return 521;
        //3. 返回的是另一个新promise, 此promise的结果就会成为新promise的结果
        return new Promise((resolve, reject) => {
            // resolve('success');
            reject('error');
        // });
    }, reason => {
        console.warn(reason);
    });

    console.log(result);
</script>

5.promise如何串连多个操作任务?

promise 的 then() 返回一个新的 promise,可以并成 then() 的链式调用,通过 then 的链式调用串联多个同步/异步任务。

let p = new Promise((resolve, reject) => {
  setTimeout(() => {
      resolve('OK');
  }, 1000);
});

p.then(value => {
  return new Promise((resolve, reject) => {
      resolve("success");
  });
}).then(value => {
  console.log(value); // success,最上边状态改变,第一个p.then回调才会执行,返回成功的promise,这里的then才会执行
}).then(value => {
  console.log(value); // undefined
})

6.promise异常穿透

当使用promise的then链式调用时, 可以在最后指定失败的回调, 前面任何操作出了异常, 都会传到最后失败的回调中处理。

<script>
    let p = new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve('OK');
            // reject('Err');
        }, 1000);
    });

    p.then(value => {
        // console.log(111);
        throw '失败啦!';
    }//,reason => {throw reason} 等价于reason => Promise.reject(reason),异常穿透使得可以省略每个then后的reason。
    ).then(value => {
        console.log(222);
    }).then(value => {
        console.log(333);
    }).catch(reason => {
        console.warn(reason);
    });
</script>

7.中断promise链的唯一方法

当使用 promise 的 then 链式调用时想在中间中断,不再调用后面的回调函数 办法:在回调函数中返回一个 pending 状态的 promise 对象。

<script>
    let p = new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve('OK');
        }, 1000);
    });

    p.then(value => {
        console.log(111);
        //有且只有一个方式
        return new Promise(() => {});
    }).then(value => {//回调函数then得在上面状态改变之后才能执行,由于上面状态是pending所以在这就卡住了
        console.log(222);
    }).then(value => {
        console.log(333);
    }).catch(reason => {
        console.warn(reason);
    });
</script>

在这里插入图片描述