最近因为公司的前端项目都是用es6写的,然后就需要我去学习,这次又看到了这个promise了,以前看到promise是因为在看到面试题到过程中遇到的,然后自己看了相关的知识,本来会以为比较简单,没想到自己一看当时一下子没反应过来,没看太懂,自己也没有遇到过使用的问题,所以比较生,现在公司的项目要用es6,自己又看过了,这次一定要把这个知识点搞懂,为以后的应用做准备,有时候一直相信,比较难的问题,但是人们又会经常提到的,一定是比较重要能提高自己水平的关键点。
好下面就来开始promise的学习。promise的出现是为了解决回调的问题的,避免了你因为回调而产生的层层嵌套问题,使得问题的表达更加的清晰,他使用有两步:
- 新建一个promsie对象,把resolve和reject传进去,
- 看一个代码例子:
var promise = new Promise(function(resolve, reject){
if (/*异步操作成功*/){
resolve(value);
}else {
reject(value);
}
})
等于说是把一些异步操作交给了promise,然后接下来就可以在状态变化的时候进行调用,
promise.then(function(value){
//success
}, function(error){
//failure
})
看起来promise的应用很简单,两步之后我们就可以应用了,再看一个实例,就是我们在ajax请求时经常会遇到的异步问题。
function getURL(URL) {
return new Promise(function (resolve, reject) {
var req = new XMLHttpRequest();
req.open('GET', URL, true);
req.onload = function () {
if (req.status === 200) {
resolve(req.responseText);
} else {
reject(new Error(req.statusText));
}
};
req.onerror = function () {
reject(new Error(req.statusText));
};
req.send();
});
}
// 运行示例
var URL = "http://httpbin.org/get";
getURL(URL).then(function onFulfilled(value){
console.log(value);
}).catch(function onRejected(error){
console.error(error);
});
但是知道了怎么用还不够,我们需要了解他的背后原理。
采用链式的then,可以指定一组按照次序调用的回调函数。这时,前一个回调函数,有可能返回的还是一个Promise对象(即有异步操作),这时后一个回调函数,就会等待该Promise对象的状态发生变化,才会被调用。
这一段话的意思是当我把一个promise对象传到另一个promise对象中去,他会等待你 传入进去的promise对象的状态,当他的状态变化时才会触发下面的promise的执行,
下面是.then他返回的是另个promise,不是原来的那个promise。也就是说前一个promise运行结束后,才会到后一个then执行,我以前还一直纠结一个问题,就是我在一个getJSON这样一个ajax请求中,如果我发生了多个promise的resolve该怎么办,执行的时候他是怎么执行的,现在我想到了,原来你在ajax请求的时候只有请求成功和失败两种情况,请求成功之后,你有可能会再次请求其他的,这个时候你点then之后就可以在状态一有变化进行调用。看一段代码,因为如果用ajax方式请求就需要写后端,有点麻烦,当然有能力的可以尝试一下,初学者先用setTimeOut进行测试练习,会更容易理解他的用法。
'use strict';
var number = 0;
function testPro() {
var thisNumber = ++number;
var log = document.getElementById('log');
log.insertAdjacentHTML('beforeend', thisNumber + ') Promise开始(异步代码开始)<br/>');
var promise = new Promise(function (resolve, reject){
window.setTimeout(function(){
resolve(thisNumber);
}, 2000);
})
promise.then(function(val){
log.insertAdjacentHTML('beforeend', val + ') Promise被满足了(异步代码结束)<br/>');
})
}
testPro();
testPro();
这是初学promise的一点心得,在后面会再讨论高级用法。
在node中,绝大部分操作都是异步的方式