关于promise的学习和拓展

2次阅读

共计 1729 个字符,预计需要花费 5 分钟才能阅读完成。

Promise 的学习和拓展


以前开发的时候偶尔会在请求中,或者其他场景中用到 promise, 只知道它是什么(链式调用,用于请求的后返回值得操作之类的), 大概怎么用,却没有深入了解。

起因:(在参考了廖雪峰的 promise 讲解后 https://www.liaoxuefeng.com/w…)

在 javascript 中,所有的代码都是单线程进行的。
由于这个“缺陷”,导致 JavaScript 的所有网络操作,浏览器事件,都必须是异步执行。异步执行可以用回调函数实现(否者在加载完 js 文件后。其他操作也不会发生了):

参数:executor 是带有 resolve 和 reject 两个参数的函数。Promise 构造函数执行时立即调用 executor 函数,resolve 和 reject 两个函数作为参数传递给 executor(executor 函数在 Promise 构造函数返回所建 promise 实例对象前被调用)。resolve 和 reject 函数被调用时,分别将 promise 的状态改为 fulfilled(完成)或 rejected(失败)。executor 内部通常会执行一些异步操作,一旦异步操作执行完毕(可能成功 / 失败),要么调用 resolve 函数来将 promise 状态改成 fulfilled,要么调用 reject 函数将 promise 的状态改为 rejected。如果在 executor 函数中抛出一个错误,那么该 promise 状态为 rejected。

由此可以知道,一个 promise 包含 3 个状态:(注意,不包含 resolve
)
pending: 初始状态,既不是成功,也不是失败状态。
fulfilled: 意味着操作成功完成。
rejected: 意味着操作失败。

function callback() {console.log('Done');
}
console.log('before setTimeout()');
setTimeout(callback, 0); // 1 秒钟后调用 callback 函数
console.log('after setTimeout()');

观察上述代码执行,在 Chrome 的控制台输出可以看到:

before setTimeout()
after setTimeout()
Done

AJAX 就是典型的异步操作

var ajax = ajaxGet('http://...');
ajax.ifSuccess(success)
    .ifFail(fail);

统一执行 AJAX 逻辑,不关心如何处理结果,然后,根据结果是成功还是失败,在将来的某个时候调用 success 函数或 fail 函数。
这个时候 promise 方法就应运而生了。


一个简单的 promise 应用
生成一个 0 - 2 之间的随机数,如果小于 1,则等待一段时间后返回成功,否则返回失败:

function test(resolve, reject) {var timeOut = Math.random() * 2;
    log('set timeout to:' + timeOut + 'seconds.');
    setTimeout(function () {if (timeOut < 1) {log('call resolve()...');
            resolve('200 OK');
        }
        else {log('call reject()...');
            reject('timeout in' + timeOut + 'seconds.');
        }
    }, timeOut * 1000);
}

有了执行函数,我们就可以用一个 Promise 对象来执行它,并在将来某个时刻获得成功或失败的结果:

var p1 = new Promise(test);
var p2 = p1.then(function (result) {console.log('成功:' + result);
});
var p3 = p2.catch(function (reason) {console.log('失败:' + reason);
});

也可以写成链式调用的形式

new Promise(test).then(function (result) {console.log('成功:' + result);
}).catch(function (reason) {console.log('失败:' + reason);
});

正文完
 0