技术原理

Javascript 进阶 11-3 创立自己的 Promise

这篇文章要来教你如何建立自己的 Promise

首先我们先来看看 Promise 的建构函式~

console.log(Promise);

https://ithelp.ithome.com.tw/upload/images/20200526/201217702hlJa523Ju.png

检查了以后发现甚幺都看不到,这个时候就要用 console.dir 针对 Promise 进行检查

console.dir(Promise);

https://ithelp.ithome.com.tw/upload/images/20200526/20121770RRJ1tKZVqf.png

之后你可以看到,如果将 Promise 实体化(new Promise),他可以用的方法就是红色框框框起来的这些。

那幺 Promise 本身作为物件,被插入的方法就是蓝色框框的这些方法:例如上一篇文章介绍到的 Promise.all();

那我们一样试着将 Promise 实体化 看看。

const a = new Promise();

console.log(a);

https://ithelp.ithome.com.tw/upload/images/20200526/20121770Z55czOc1yM.png

挖~为什幺会跳错呢?

其实是因为在将 Promise 实体化的时候,同时必须传入一个 callback 的 function 才行。

const a = new Promise(() => {
            
});

console.log(a);

https://ithelp.ithome.com.tw/upload/images/20200526/20121770HapCetvLwa.png

之后你就会发现,原来这个 Promise 是 pending 的状态,很正常,因为我们还没有设定,怎样的状况是 resolve ,怎样的状况是 reject 。

所以首先我们得先传入 resolve 以及 reject 的参数,并且同时只能回传其中一种状态。

const a = new Promise((resolve, reject) => {
    resolve('成功');
});

console.log(a);

https://ithelp.ithome.com.tw/upload/images/20200526/20121770Iunsas8uMw.png

有没有看到,当如果我们直接执行 resolve 的语法的话,Promise 的状态就从 pending 改为 resolved。

那幺如果我们要取得 resolve 所传入的参数,就要使用 then 的语法去承接

const a = new Promise((resolve, reject) => {
    resolve('成功');
});

console.log(a);
a
    .then((res) => {
        console.log(res);
    });

https://ithelp.ithome.com.tw/upload/images/20200526/20121770h5CbWVigOX.png

那幺今天如果是失败的 reject 的话呢?

const a = new Promise((resolve, reject) => {
    reject('失败');
});

console.log(a);
a
    .then((res) => {
        console.log(res);
    });

https://ithelp.ithome.com.tw/upload/images/20200526/20121770F2adRet5bF.png

因为我们没有使用 .catch 去承接失败,所以这边他就提示 Uncaught 的状态。

const a = new Promise((resolve, reject) => {
    reject('失败');
});

a
    .then((res) => {
        console.log(res);
    })
    .catch((err) => {
        console.log(err);
    });

https://ithelp.ithome.com.tw/upload/images/20200526/20121770i658P0LQUu.png

这样就完美接到失败的讯息噜!

另外其中的 res 以及 err 都是自订的参数名称,你要取甚幺名字都无所谓喔!

以上就是实际上 Promise 的实际操作概念,但是实务上我们不太会这样使用。

原因在于,a 说到底也只是个物件而已,如果我们有其他的参数要进行判断、计算、调整,只用物件是没有办法的,必需使用一个函式,回传这个 Promise 的物件,这样就可以同时传入参数进行处理,又可以进行 Promise 的定义

那幺关于这个函式,不论你是要使用函式陈述式还是函式表达式都是可以的喔!

範例这边就先使用函式陈述式来进行开始

// 定义
function promiseFn (num) {
    return new Promise( (resolve, reject) => {
        setTimeout(() => {
            if (num) {
                resolve('成功');
            } else {
                reject('失败');
            }
        }, 10);
    });
}

// 执行
promiseFn(1)
    .then((res) => {
        console.log(res);
    })
    .catch((err) => {
        console.log(err);
    });

console.log('Code End');

这边使用的範例就是上一篇文章的範例,现在这样看起来是不是就懂了呢?

利用 num 的参数判断是真值还是假值,进而执行 resolve 还是 reject~

执行的时候再用 then 以及 catch 分别接收成功以及失败的结果。

只是最后不同的地方在于,我这边多加了一个 Code End,大家想看看,这样执行的顺序是甚幺呢,是结果会先出来,还是 Code End 会先出来呢?

https://ithelp.ithome.com.tw/upload/images/20200526/20121770bEbnf9S7a5.png

答案也是先 Code End 出来,很明显因为 setTimeout 就是非同步,所以今天就算执行延迟毫秒改成0,也还是一样。

那幺执行顺序会是怎幺样呢?

// 定义
function promiseFn (num) {
    console.log(1);
    return new Promise( (resolve, reject) => {
        console.log(2);
        setTimeout(() => {
            if (num) {
                resolve('成功');
            } else {
                reject('失败');
            }
        }, 10);
    });
}

// 执行
promiseFn(1)
    .then((res) => {
        console.log(res);
    })
    .catch((err) => {
        console.log(err);
    });

console.log('Code End');

这边加上了 1 跟 2 ,也就是说在执行完 2 之后,就先把 setTimeout 放到事件伫列中,在继续执行 Code End,之后才来执行 setTimeout 的内容。

那幺以上就是基本的 Promise 介绍,透过下一篇文章的内容,可以让你创建自己的 Promise 的时候更为方便喔!

如果没有问题的话就可以继续往下一篇文章迈进噜~汪汪

你也可能喜欢

发表评论

您的电子邮件地址不会被公开。 必填项已用 * 标注

提示:点击验证后方可评论!

插入图片
苏州人工智能培训班 投稿者
我还没有学会写个人说明!
最近文章
  • * 没有更多文章了
  • 热门搜索

    分类目录