[英]Chaining function with then doesn't work correctly
嘿,我遇到了一个问题,我用 .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 函数在它们之前运行,因此其中的 users 变量为空。
我该如何解决?
.then
接受一个函数作为参数,但在
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'));
$.ajax
返回一个类似promise 的对象。 因此,通过在函数中的then
返回来自 ajax 调用的数据,可以充分利用它。
请注意,我在他们的回答中使用了@CertainPerformance 的建议之一来解决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
收集到一个对象中; 您可以轻松地使用数组。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.