今天做项目的时候遇到了一个问题,当我在请求完后端数据的时候,想去立刻打印出请求出来的信息时,怎么打印都是空的,但是出来这个请求方法之后他又有数值了,于是我很纳闷,研究了1个小时找出了原因。
new Promise((resolve, reject) => {
wx.request({
url: baseUrl + url,
data: data || {},
method: method || 'GET',
success: (result) => {
resolve(result);
},
fail: (err) => {
reject(err);
},
complete: () => {
wx.hideLoading();
},
}).then(res => {
console.log("数据请求成功");
// 然后设置数据 data
this.setData({
data: res.data,
});
});
console.log(data);
// 这里打印出来为空
})
就像上面的代码一样,打印出来的结果为空,但是出去这个方法,再打印就有了,于是我产生了疑惑,然后查阅资料。
JavaScript
是一门单线程语言。Event Loop
(事件循环)是 JavaScript
的执行机制。下面我不会直接回答那个问题,而是举别的例子,如果这些例子都搞明白了,那么上面的代码有什么问题相信大家也就都知道了。
大家首先来看一下这段代码:
setTimeout(function(){
console.log('1.定时器开始')
});
new Promise(function(resolve){
console.log('2.Promise开始');
resolve();
}).then(function(){
console.log('3.执行then函数')
});
console.log('4.代码执行结束');
这段代码的执行结果是:
Promise
开始then
函数上面也提到了, JavaScript 是一门单线程的语言,所以我们看到的多线程都是 模拟出来 的,都是纸老虎。
单线程就是使用队列的机制,所有的任务都排着队的执行,在前面排队的任务就先执行,即 先进先出 。
异步的任务不会先执行,而是先放入一个事件列表,等到主线任务执行完之后再去执行这些事件列表中的数据。
Event Table
事件列表中。Event queue
事件队列,等待执行。(Event Loop)
下面介绍几个异步函数
setTimeout
异步函数,可以延迟执行。
setTimeout(() => {
console.log('1');
},3000)
console.log('2');
执行结果是:2 、1 。
setInterval
两个定时器兄弟,原理一样,只不过setInterval会每隔指定的时间将注册的函数置入Event Queue。
Promise
Promise 对象是用于异步操作的。
来看一段代码:
$.ajax({
url:www.javascript.com,
data:data,
success:() => {
console.log('第一个数据返回成功!');
$.ajax({
url:www.javascript.com,
data:data,
success:() => {
console.log('第二个数据返回成功!');
...如果还有再继续
}
})
}
})
我们可以使用 Promise
对象改造该方法:
function abc(url,param){
return new Promise(function (resolve, reject) {
request(url, param, function(){
resolve('数据请求成功了');
}, reject);
});
}
abc.then(function(data){
console.log(date);//'第一个数据请求成功了';
return new Promise(function (resolve, reject) {
request(url, param, function(){
resolve('数据请求成功了');
}, reject)
});
}).then(function(){
console.log(date);//'第二个数据请求成功了';
});
除了广义的同步任务和异步任务,我们对任务有更精细的定义:
Promise
,process.nextTicksetTimeout(function() {
console.log('setTimeout');
})
new Promise(function(resolve) {
console.log('promise');
resolve();
}).then(function() {
console.log('then');
})
console.log('console');
执行结果为:promise
,console
,then
,setTimeout
。
setTimeout
,那么注册后把他放到宏任务事件队列 Event Queue
。console.log()
,立即执行。总结题
console.log('1');
setTimeout(function() {
console.log('2');
process.nextTick(function() {
console.log('3');
})
new Promise(function(resolve) {
console.log('4');
resolve();
}).then(function() {
console.log('5')
})
})
process.nextTick(function() {
console.log('6');
})
new Promise(function(resolve) {
console.log('7');
resolve();
}).then(function() {
console.log('8')
})
setTimeout(function() {
console.log('9');
process.nextTick(function() {
console.log('10');
})
new Promise(function(resolve) {
console.log('11');
resolve();
}).then(function() {
console.log('12')
})
})
附上输出结果:1,7,6,8,2,4,3,5,9,11,10,12