今天不想写太多的文字,就来两段代码吧,我今天最有用的收获应该就是在这代码中,下面我就将它们分享出来
代码片段一
var p = Promise.resolve();
var ret = null;
console.log("outer1");
var ary = [23, 34, 45, 56, 67];
for(var i of ary) {
console.log("test-for" , i);
p = p.then(function(val) {
console.log("test-promise" , i);
console.log(val);
return val;
});
}
console.log("outer2");
你完全可以把上面的代码放在控制台下运行,当然浏览器得支持Promise
下面看下结果:
这个结果你想到了吗?我就来解析一下,JS的代码的执行顺序是自上而下的(参考这里),所以我想outer1, test-for 一直到outer2这部分的输出你应该是可以看懂的,当然我知道你此时是有疑问的,then是属于异步操作的所以每次都会将它放入一个异步队列中,所以这部分是最后执行的,所以之后才会出现test-promise这些输出,then
里面的第一个参数就是onFulfilled状态下调用的函数,这个函数中引用了i
这个变量,但是会发先它的输出都是5,要知道在同步部分执行结束之后,i
的值就是5,所以输出5也是没得说的
关于为什么输出val
的值都是undefined
呢?
这次就需要你对着代码看这段话了,首先第一行Promise.resolve()
执行之后,会返回一个Promise对象,也就是说此时的p就是一个Promise对象,而执行完p.then(...)
之后会返回一个新的Promise对象,现在我打算将这个Promise对象“晾出来”给你看看,如下,这个Promise是执行完Promise.resolve()
所产生的。
我顺便也将其他的Promise也输出了,当然是和上面一样的,但是请注意,它们真的不是同一个Promise。
下面正式解释 为什么输出了”undefined”
Promise.resolve()
相当于下面的代码
new Promise(function(resolve, reject) {
resolve();
})
关于then部分的代码,其实可以看成是这样的
new Promise(function(resolve, reject) {
resolve();
}).then(function(val) {
return val;
}).then(function(val) {
//同上
}).then(function(val) {
//同上
}).then(function(val) {
//同上
}).then(function(val) {
//同上
});
调用resolve的时候,并没有传递参数,所以第一个形参val的值就是undefined
,因为存在return
,所以第二个形参val的值就是undefined
,其他的同理可得
代码片段二
在看下面的代码之前,你可以先去了解一下,fetch(参考这里)、async/await(参考这里)
分成两部分来看吧,下面是第一个部分
async function logInOrder(urls) {
for (const url of urls) {
const response = await fetch(url);
console.log(await response.text());
}
}
logInOrder(['https://httpbin.org/get', 'https://azu.github.io/promises-book/json/comment.json']);
如果你看了需要了解的东西或者说你之前就有所了解,那么我想上面的代码的输出结果你大致可以知道它们输出的是什么
下面就是第二部分,也是我今天收获的地方
function toPromise(n) {
return new Promise((resolve) => {
resolve(n);
})
}
async function test(data) {
for(const n of data) {
console.log(await toPromise(n)); //这个输出语句在之后我会进行变动
}
}
test([1, 3, 5, 7, 8]);
输出结果是:
1 3 5 7 8
当时我就比较好奇,为什么会是这样的呢?然后又进行了下面的输出
console.log(toPromise(n));
输出结果如下:
看到这里有没有发现,不加await
的时候返回的就是一个Promsie对象,而加上await
返回的值和Promise中的[[PromiseValue]]
的值是一样的,“await
命令就是内部then
命令的语法糖”,现在我看到的就是await会将一个Promise对象的PromiseValue
返回
如果你看到我写的Fetch那篇博客了,你就应该知道Fetch是基于Promise实现的,所以,我又特地将第一部分的代码进行了修改,其实也就是加了一句输出
async function logInOrder(urls) {
for (const url of urls) {
console.log(fetch(url));
const response = await fetch(url);
console.log(await response.text());
}
}
logInOrder(['https://httpbin.org/get', 'https://azu.github.io/promises-book/json/comment.json']);
输出结果如下:
所以也就说明了Fetch(url)的返回值就是一个Promise对象,所以也就是基于Promise的了
然后,我又将第一部分的代码进行了修改
async function logInOrder(urls) {
for (const url of urls) {
console.log(fetch(await fetch(url)));
}
}
logInOrder(['https://httpbin.org/get', 'https://azu.github.io/promises-book/json/comment.json']);
输出结果如下:
有没有发现,加上await的输出和fetch(url)
获得的Promise
对象的[[PromisValue]]
的值是一样的
目前我的理解就是上面那些,欢迎交流,也欢迎指出我的不足