嘿,我遇到了一个问题,我的函数链接到.then不能正确地工作,而不是按照它们应有的顺序工作。
我的代码:
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
</head>
<body>
<script src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.3.1.min.js"></script>
<script>
var users = [];
var user = null;
function restCallA() {
return $.ajax({
url: "https://reqres.in/api/users?page=2",
type: "GET",
success: function(response) {
users = response.data;
console.log("users", users);
}
});
}
function restCallB() {
return $.ajax({
url: "https://reqres.in/api/users/2",
type: "GET",
success: function(response) {
user = response.data;
console.log("user", user);
}
});
}
function myFun(testArg) {
users.push(user);
console.log("why users is null?", testArg, users);
}
$(function() {
restCallA()
.then(restCallB)
.then(myFun("test"));
});
</script>
</body>
</html>
输出:
myFun函数上的users变量应具有来自第一个restCall的所有数据,并将来自第二个restCall的数据推送到同一变量。 变量确实获取了数据,但是myFun函数在它们之前运行,因此其中的用户变量为null。
我该如何解决?
答案 0 :(得分:1)
.then
接受 function 作为参数,但在
restCallA()
.then(restCallB)
.then(myFun("test"));
您立即调用 myFun
,并将其返回值传递给第二个.then
。评估结果为:
restCallA()
.then(restCallB)
.then(undefined);
myFun
立即运行 ,而解释器尝试将Promise链放在一起(在响应返回之前)。
通过调用 myFun
的函数代替:
restCallA()
.then(restCallB)
.then(() => myFun("test"));
您也可以使用.bind
,它会创建具有所需参数的函数,但不会调用它:
restCallA()
.then(restCallB)
.then(myFun.bind(undefined, "test"));
var users = [];
var user = null;
function restCallA() {
return $.ajax({
url: "https://reqres.in/api/users?page=2",
type: "GET",
success: function(response) {
users = response.data;
console.log("users", users);
}
});
}
function restCallB() {
return $.ajax({
url: "https://reqres.in/api/users/2",
type: "GET",
success: function(response) {
user = response.data;
console.log("user", user);
}
});
}
function myFun(testArg) {
users.push(user);
console.log("why users is null?", testArg, users);
}
$(function() {
restCallA()
.then(restCallB)
.then(() => myFun("test"));
});
<script src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.3.1.min.js"></script>
仅当函数返回函数时,才在.then
的参数列表中调用函数,例如:
const fnThatReturnsFn = arg => resolveValue => console.log(arg, resolveValue);
someProm()
.then(fnThatReturnsFn('somearg'));
答案 1 :(得分:0)
$.ajax
返回类似promise的对象。因此可以通过在函数内的then
中从ajax调用中返回数据来利用这一点。
请注意,我已使用@CertainPerformance's suggestions in their answer中的一个来解决myFun
的问题。
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
</head>
<body>
<script src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.3.1.min.js"></script>
<script>
function restCallA() {
return $.ajax({
url: "https://reqres.in/api/users?page=2",
type: "GET"
}).then(response => response.data);
}
function restCallB(users) {
return $.ajax({
url: "https://reqres.in/api/users/2",
type: "GET"
}).then(response => {
return {
// ES2015 method for adding a property named "users" with the value of the users variable
users,
user: response.data
};
});
}
function myFun(testArg, usersAndUser) {
usersAndUser.users.push(usersAndUser.user);
console.log(testArg);
}
$(function() {
restCallA()
.then(restCallB)
.then((usersAndUser) => myFun("test", usersAndUser));
});
</script>
</body>
</html>
请注意,我正在使用一个对象将users
和user
收集到一个对象中;您可以轻松地使用数组。