JS--Promise--使用/教程/实例

原文网址:JS--Promise--使用/教程/实例_IT利刃出鞘的博客-CSDN博客

简介

说明

本文用示例介绍JavaScript的Promise。它是ES6新增的特性。

Promise的用途

  1. 用来异步编程
  2. 解决回调地狱(也称为:厄运金字塔)
    1. 在异步调用中再次进行异步回调,如果嵌套的层级太多,会导致难以维护。

Promise 的三种状态

  1. pending:等待(初始状态)
    1. 在 resolve 被调用时变为 "fulfilled"。
    2. 在reject 被调用时变为 "rejected" 。
  2. fulfilled:已完成
  3. rejected:已失败。(已拒绝)

状态变为resolved 或 rejected 之后,就不会再次改变。这两个状态被称为 “settled”(已定型)。

用法简介

简述

Promise 都有这些内容:构造函数、对象的实例方法、静态方法

  1. 1个构造函数:new Promise
  2. 3个对象的实例方法:.then 和 .catch 和 finally(不常用)
  3. 5个静态方法:Promise.all、Promise.allSettled、Promise.race、Promise.resolve、Promise.reject

then与catch

        .catch(f) 调用是 .then(null, f) 的完全的模拟,它只是一个简写形式。

        then与catch只用一个即可。一般用then,因为它可以处理成功(fulfilled)与失败(rejected),而catch只能处理失败(rejected)。

下边程序中,会进行reject,后续then会执行,.catch不会执行,finally会执行。

let promise = new Promise(function (resolve, reject) {
    setTimeout(() => {
        reject("定时任务结果(reject)");
    }, 1000);
});

promise
    .then(
        result => console.log("成功(then):" + result),
        error => console.log("错误(then):" + error)
    )
    .catch(
        error => console.log("错误(catch):" + error)
    )
    .finally(
        () => console.log("运行结束(finally)")
    );

结果

错误(then):定时任务结果(reject)
运行结束(finally)

resolve与reject

resolve方法:

        通过回调里的 resolve(data) 将这个状态标记为 fulfilled,然后进行下一步 then((data)=>{//do something})。resolve 里的data就是你要传入 then 的data。

reject方法:

        通过回调里的 reject(data) 将这个状态标记为 rejected,然后进行下一步 then((data1, data2)=>{//do something})。resolve 里的data就是你要传入 then 的data2。

executor 只能调用一个 resolve 或一个 reject ,所有其他的 resolve 和 reject 的调用都会被忽略:

let promise = new Promise(function(resolve, reject) {
    resolve("done");
    reject(new Error("…"));         // 被忽略
    setTimeout(() => resolve("…")); // 被忽略
});

示例:异步编程

示例1:resolve(成功)

let promise = new Promise(function (resolve, reject) {
    setTimeout(() => {
        resolve("定时任务结果(resolve)");
    }, 1000);
});

promise
    .then(
        result => console.log("成功(then):" + result),
        error => console.log("错误(then):" + error)
    )
    .finally(
        () => console.log("运行结束(finally)")
    );

结果

成功(then):定时任务结果(resolve)
运行结束(finally)

示例2:reject(失败)

let promise = new Promise(function (resolve, reject) {
    setTimeout(() => {
        reject("定时任务结果(reject)");
    }, 1000);
});

promise
    .then(
        result => console.log("成功(then):" + result),
        error => console.log("错误(then):" + error)
    )
    .finally(
        () => console.log("运行结束(finally)")
    );

结果

错误(then):定时任务结果(reject)
运行结束(finally)

示例:解决回调地狱

什么是回调地域?

在异步调用中再次进行异步回调,如果嵌套的层级太多,会导致难以维护。这就是回调地狱。

例如:使用ajax请求url,成功后再请求url1,成功后再请求url2,代码会是下边这个样子:

ajax(url, () => {
    // 处理逻辑
    ajax(url1, () => {
        // 处理逻辑
        ajax(url2, () => {
            // 处理逻辑
        })
    })
})

为了方便演示,本处采用定时任务的方式进行演示。

需求:每1秒钟输出一次,分别输出:first、second、third、end。

复现回调地狱

let fn = function (order, callback) {
    setTimeout(function () {
        console.log(order);
        callback();
    }, 1000);
}

fn("first", function () {
    fn("second", function () {
        fn("third", function () {
            console.log("end");
        });
    });
});

结果

first
second
third
end

Promise解决回调地狱

let fn = function (order) {
    return new Promise(function (resolve, reject) {
        setTimeout(function () {
            console.log(order);
            //异步操作执行完后执行 resolve() 函数
            resolve();
        }, 1000);
    });
}
fn("first")
    .then(function () {
        //仍然返回一个 Promise 对象
        return fn("second");
    })
    .then(function () {
        return fn("third");
    })
    .then(function () {
        console.log('end');
    })

结果

first
second
third
end

async + await 解决回调地狱

async + await是对promise的进一步封装。

let fnTimeOut = function (order) {
    return new Promise(function (resolve, reject) {
            setTimeout(function () {
                console.log(order);
                //异步操作执行完后执行 resolve() 函数
                resolve();
            }, 1000);
        }
    );
};

async function fn() {
    let first = await fnTimeOut("first");
    let second = await fnTimeOut("second");
    let third = await fnTimeOut("third");
    console.log("end");
}

fn();

结果

first
second
third
end


 

猜你喜欢

转载自blog.csdn.net/feiying0canglang/article/details/122267112