then在鏈式調用時,會等前一個then或者函數執行完畢,返回狀態,才會執行回調函數。
(1)代碼順序執行,第一步調用了函數cook ,cook執行返回了一個promise,promise返回的是成功狀態,即resolve('雞蛋炒飯'),那么參數“'雞蛋炒飯'”會傳遞給下一個then。
(2)第一個then接收“'雞蛋炒飯'”,執行then的回調。回調中調用了eat,把'雞蛋炒飯'作為參數傳遞給了eat。eat執行(里面輸出的步驟就不講了,代碼順序執行,輸出的“開始吃飯”等等),並返回promise,promise返回的是成功狀態,並給下一個then傳遞了參數'一塊碗和一雙筷子'。
(3)第二個then接收'一塊碗和一雙筷子','執行then的回調。回調中調用了wash,把'一塊碗和一雙筷子'作為參數傳遞給了wash。wash執行,並返回promise,promise返回成功狀態,並給下一個then傳遞了參數'干凈的碗筷'。
(4)最后一個then,接收'干凈的碗筷”,執行回調,輸出'干凈的碗筷”。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<script src="https://cdn.bootcss.com/jquery/1.12.4/jquery.js"></script>
<script type="text/javascript">
function cook() {
console.log('開始做飯。');
var p = new Promise(function(resolve, reject){
setTimeout(function() {
console.log('做飯完畢!');
resolve('雞蛋炒飯');
}, 1000);
});
return p;
}
function eat(data) {
console.log('開始吃飯:' + data);
var p = new Promise(function(resolve, reject) {
setTimeout(function() {
console.log('吃飯完畢!');
resolve('一塊碗和一雙筷子');// resolve()的值會傳遞給then中function的data參數,供下一個方法使用。
}, 2000);
});
//這里的return的作用是把第一個回調函數的返回結果作為參數,傳遞給第二個回調函數
return p;
}
function wash(data) {
console.log('開始洗碗:' + data);
var p = new Promise(function(resolve, reject) {
setTimeout(function() {
console.log('洗碗完畢!');
resolve('干凈的碗筷');
}, 2000);
});
return p;
}
//補充代碼
cook().then(resolve => {
return eat(resolve) //第一個回調函數完成以后,會將返回結果作為參數,傳入第二個回調函數。所以這里要用return返回函數去傳參。
}).then(resolve => {
return wash(resolve);
}).then(resolve => {
//在Promise實例生成以后,可以用then方法分別指定resolved狀態和rejected狀態的回調函數。
//then方法執行的是resolve這個回調,並且這個函數都接受Promise對象傳出的值作為參數。而這里“雞蛋炒飯”就是作為參數傳遞的
console.log(resolve); //resolve中的值是傳遞到then方法中的參數,只有在then中通過console.log輸出傳入的參數,才可以在控制台查看到消息
})
//也可以像下面這樣寫,因為這三個函數本身設置的有return才可以這樣直接寫
//下一個then的回調函數,會等上一個then中的回調函數執行完畢,返回promise狀態,就執行.
//首先eat,wash本身就是一個函數,所以可以直接作為then中的回到函數.
//然后eat,wash函數內部也返回了promise,所以這樣寫沒有問題.
cook()
.then(eat)
.then(wash);
</script>
</body>
</html>
.then 中 1.return返回一個值,將返回的值作為下一個then中回調函數的參數值 2.如果返回的是一個promise對象,將這個Promise 接受狀態的回調函數中參數值作為下一個then回調函數的參數值。
.then(fn(argument){})中的匿名函數實際上就是執行實例化Promise對象中的resolve(),當resolve(argument)中有參數時,可以將參數傳給.then()中的匿名函數
這里原理都是一樣的,就是Promise實例生成以后,可以用then方法分別指定resolved狀態和rejected狀態的回調函數。且都會返回一個Promise實例,所以可以鏈式調用then方法,上一個的返回值,可以作為下一個的參數。
