87,907
社区成员
发帖
与我相关
我的任务
分享
<!DOCTYPE html>
<html>
<head>
<title></title>
<script type="text/javascript">
Promise.resolve('foo')
// 1. Receive "foo" concatenate "bar" to it and resolve that to the next then
.then(function(string) {
return new Promise(function(resolve, reject) {
setTimeout(function() {
string += 'bar';
resolve(string);
}, 1);
});
})
// 2. receive "foobar", register a callback function to work on that string
// and print it to the console, but not before return the unworked on
// string to the next then
.then(function(string) {
setTimeout(function() {
string += 'baz';
console.log(string);
}, 1)
return string;
})
// 3. print helpful messages about how the code in this section will be run
// before string is actually processed by the mocked asynchronous code in the
// prior then block.
.then(function(string) {
console.log("Last Then: oops... didn't bother to instantiate and return " +
"a promise in the prior then so the sequence may be a bit " +
"surprising");
// Note that `string` will not have the 'baz' bit of it at this point. This
// is because we mocked that to happen asynchronously with a setTimeout function
console.log(string);
});
</script>
</head>
<body>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<title></title>
<script type="text/javascript">
Promise.resolve('foo')
//第一个promise已经resolve,将'foo'传入第一个then。
.then(function(string) {
return new Promise(function(resolve, reject) {
setTimeout(function() {
string += 'bar';
resolve(string);
}, 1000);//将1ms改为1s更易观察
});
})
//第一个then中的函数返回一个promise对象,该promise对象状态为pending,
//根据‘如果then中的回调函数返回一个未定状态(pending)的Promise,那么then返回Promise的状态也是未定的,
//并且它的终态与那个Promise的终态相同;同时,它变为终态时调用的回调函数参数与那个Promise变为终态时的回调函数的参数是相同的。
//’摘自MDN。
//直到setTimeout时间到达,调用resolve(string),状态变为fulfilled(resolve),才调用下一个then方法。
.then(function(string) {
setTimeout(function() {
string += 'baz';
console.log(string);
}, 1000)
return string;
})
// 在第二个then中,先调用setTimeout
//(估计题主的问题出在这里,setTimeout调用定时器后不会等待计时完成,而是继续执行下面的代码,
// 在1s的定时结束后再将其中的程序加入任务队列,不理解可以再看看关于MacroTask事件循环相关资料),
// 然后跳到return string,由于setTimeout内代码尚未执行,此时string == 'foobar'。
// 且根据 ‘如果then中的回调函数返回一个值,那么then返回的Promise将会成为接受状态,
// 并且将返回的值作为接受状态的回调函数的参数值。’摘自MDN。
// 因此进入下一个then,且该段代码没有任何延时。
.then(function(string) {
console.log("Last Then: oops... didn't bother to instantiate and return " +
"a promise in the prior then so the sequence may be a bit " +
"surprising");
console.log(string);
});
//由于第二个then中return的string值为'foobar',因此先输出'foobar'。
// 并在前面的1s定时结束后执行string += 'baz', 最后输出foobarbaz。
</script>
</head>
<body>
</body>
</html>
Promise.prototype.then = function(onFulfilled,onRejected){
var promise = this;
// 每次返回一个promise,保证是可thenable的
return Promise(function(resolve,reject){
function callback(value){
var ret = isFunction(onFulfilled) && onFulfilled(value) || value;
if(isThenable(ret)){
ret.then(function(value){
resolve(value);
},function(reason){
reject(reason);
});
}else{
resolve(ret);
}
}
function errback(reason){
reason = isFunction(onRejected) && onRejected(reason) || reason;
reject(reason);
}
if(promise._status === PENDING){
promise._resolves.push(callback);
promise._rejects.push(errback);
}else if(promise._status === FULFILLED){ // 状态改变后的then操作,立刻执行
callback(promise._value);
}else if(promise._status === REJECTED){
errback(promise._reason);
}
});
}
<!DOCTYPE html>
<html>
<head>
<title></title>
<script type="text/javascript">
Promise.resolve('foo')
// 1. Receive "foo" concatenate "bar" to it and resolve that to the next then
.then(function(string) {
console.log(1);
return new Promise(function(resolve, reject) {
setTimeout(function() {
console.log(11);
string += 'bar';
resolve(string);
}, 1);
});
})
// 2. receive "foobar", register a callback function to work on that string
// and print it to the console, but not before return the unworked on
// string to the next then
.then(function(string) {
console.log(2);
setTimeout(function() {
string += 'baz';
console.log(string);
}, 1)
return string;
})
// 3. print helpful messages about how the code in this section will be run
// before string is actually processed by the mocked asynchronous code in the
// prior then block.
.then(function(string) {
console.log(3);
console.log("Last Then: oops... didn't bother to instantiate and return " +
"a promise in the prior then so the sequence may be a bit " +
"surprising");
// Note that `string` will not have the 'baz' bit of it at this point. This
// is because we mocked that to happen asynchronously with a setTimeout function
console.log(string);
});
</script>
</head>
<body>
</body>
</html>
Promise.resolve('foo')
.then(function(string) {
console.log(1);
return new Promise(function(resolve, reject) {
setTimeout(function() {
string += 'bar';
resolve(string);
}, 1);
});
})
.then(function(string) {
console.log(2);
setTimeout(function() {
string += 'baz';
console.log(string);
}, 1)
return string;
})
.then(function(string) {
console.log(3);
console.log("Last Then: oops... didn't bother to instantiate and return " +
"a promise in the prior then so the sequence may be a bit " +
"surprising");
console.log(string);
});
这样就看出来了