濮阳前端开发招聘|前端开发校园招聘|前端开发手机端适配问题
参考的书籍是:
1.http://es6.ruanyifeng.com/#docs/promise;
2.http://liubin.org/promises-book/;
3.《你不知道的JavaScript中卷》、《英文版》。
本文是第二篇。
第一篇文章对相关术语说的不详细,本文详细说说。
先看一下下面的代码:
[quote]var p = new Promise(function(resolve, reject) {
resolve(20);
});
p.then(
function onFulfilled() {},
function onRejected() {}
);[/quote]
1.基本术语
其中promise表示承诺,即对某一件事情的承诺:这个事情,交给我了,你放心吧。
然而此承诺是有状态的,进行中、已完成、已拒绝。
其中已完成是指,事情办成了,而拒绝是指,事情办砸了。
不论是办成还是办砸,那么此事情都是办完了。
办完了,就是说此承诺已决议了。
而得到承诺的人,会对承诺的决议结果(完成或拒绝)会所响应,未决议是不会相应的。
这里的几个名词有对应的英文,
状态:进行中(pending)、已完成(fulfilled)、已拒绝(rejected)
已决议(resolved):已完成、已拒绝
未决议:进行中
响应:完成回调(onFulfilled)、拒绝回调(onRejected)
注:状态可以通过console.log查看其[[PromiseStatus]]属性值。
参考文献一上面认为,已完成也用resolved单词表示,浏览器打印的结果确实是这样的。
本文更偏向于参考文献3的观点,认为resolve是决议,状态结果是包含完成的,个人觉得这样会更好理解一些。请看下面的论述。
2.resolve是决议不只是完成
看上面的代码,我们发现,构造函数的参数(函数)的参数传递的名字是resolve和reject,并不是fulfill和reject。
虽然参数名字可以随便起,但是用resolve而不是fulfill是有用意的。
这里我们把resolve和reject当作动词来用,
调用了reject表示,状态进入已拒绝。
调用resolve表示,状态结果需要进一步决议,最终结果可能是未决议,也可能是已决议(已完成、已拒绝)。
这里有必要再强调的一点是单词resolve,是决议而不是完成的意思。看如下的代码:
html 代码
<script>
var p = new Promise(function (resolve, reject) {
resolve(Promise.reject(‘no!’));
});
p.then(
function onFulfilled() { },
function onRejected(msg) {
alert(msg);
}
);
</script>
上面的代码中,构造函数内部虽然调用的是resolve,但是then方法注册的拒绝回调触发了。
所以Promise.resolve其api的含义不是类似于Promise.reject那样,
直接生成一个状态为完成的promise实例。
而是说看参数情况,我们决议一下吧:
html 代码
<script>
var p = Promise.resolve(30);
p.then(
function (value) {
alert(value);
},
function () { }
);
</script>
上面走的是完成回调,说明p的状态决议成了完成。
如果参数已经是promise实例的话,直接返回该实例:
html 代码
<script>
var p = Promise.resolve(new Promise(function (resolve, reject) {
reject(‘no!’)
}));
p.then(
function () {
},
function (msg) {
alert(msg);
}
);
</script>
当然上述实例p的决议状态是拒绝。
如果传进是thenable,会封装成promise实例:
html 代码
<script>
var o = {
then: function (resolve, reject) {
reject(‘no’);
}
};
var p = Promise.resolve(o);
p.then(
function () {
},
function (msg) {
alert(msg);
}
);
</script>
来个一直等待中的情形。
html 代码
<script>
var p = Promise.resolve(new Promise(function (resolve, reject) {
alert(‘unresolved’);
}));
p.then(
function () {
alert(‘fulfilled’)
},
function () {
alert(‘rejected’);
}
);
</script>
其实,我们可以这么想一下,某人求我办件事情,我转而拜托另一个人,进而把他给我的承诺抛给了之前的那个某人。
resolve表示决议的结果取决于另一个人,他可能完成,可能拒绝,甚至也可能一直处于进行中。
3.完成值和拒绝值
不管决议的结果是完成还是拒绝,都会相应的拿到最终的值。
比如上面的30是完成值,no!是拒绝值。
完成值,总是需要编程给出的,而拒绝值一般也称为拒绝原因。
拒绝值,不一定需要编程给出:
html 代码
<script>
var p = new Promise(function (resolve, reject) {
throw new Error(‘no!’);
});
p.then(
function () {
},
function (msg) {
alert(msg);
}
);
</script>
上面是直接抛出异常,假如是语法错误呢:
html 代码
<script>
var p = new Promise(function (resolve, reject) {
xxx
});
p.then(
function () {
},
function (msg) {
alert(msg);
}
);
</script>
看到resolve调用时,可以传进promise实例,那么reject也传一下试试:
html 代码
<script>
var p = new Promise(function (resolve, reject) {
reject(Promise.resolve(2));
});
p.then(
function () {
},
function (msg) {
alert(msg);
}
);
</script>
证明了,reject传进的东西,只会当成拒绝值,而不像resolve有递归的味道在里面。
注:此值可以通过console.log查看其属性[[PromiseValue]]。
4.只能决议一次
决议的结果,要么不决议(未决议,pending),要么完成,要么拒绝,只能3选一。
html 代码
<script>
var p = new Promise(function (resolve, reject) {
resolve(2);
reject(‘no!’);
});
p.then(
function (value) {
alert(value);
},
function (msg) {
alert(msg);
}
);
</script>
上面的代码中,可以看出如果一开始决议是完成的话,那么后面的拒绝就没有用了。
关于决议只能有一次机会,通过点击按钮决议能更好的说明:
html 代码
<button id=”success”>success</button>
<button id=”failure”>failure</button>
<script>
var s = document.querySelector(‘#success’);
var f = document.querySelector(‘#failure’);
var resultOfPromise = new Promise(function (resolve, reject) {
s.onclick = function () {
resolve();
};
f.onclick = function () {
reject();
};
});
resultOfPromise.then(
function () {
alert(‘success’);
},
function () {
alert(‘failure’)
}
);
</script>
如果你知道构造函数的参数(是个函数)是同步执行的话,
可能会想我在外边并且异步决议的话,是否也是这样的,答案仍然是的。
html 代码
<script>
var outer = {};
var p = new Promise(function (resolve, reject) {
outer.resolve = resolve;
outer.reject = reject;
});
p.then(
function (value) {
alert(value);
},
function (msg) {
alert(msg);
}
);
setTimeout(function () {
outer.resolve(2);
outer.reject(‘no’);
outer.resolve(3);
}, 1000);
</script>
其实这种写法有点像Deferred了。
这个第4点,个人觉得是promise的最重要一点。
前端开发技能点|前端开发vscode插件|web 前端开发技术ppt
评论前必须登录!
注册