本文介绍了我试图理解如何在javascript中使用promises,但我的脚本从不执行“Then”。的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个脚本设置了一定数量的用户名,然后为每个用户名运行一个获取请求来抽取API端点以获取每个用户的Json信息。然后我想将这些信息放入一个数组供以后使用,并发现我必须使用promises,这是我以前从未使用过的。我仔细阅读了这篇文章:和此:我在这里阅读了Felix Kling的回复:并且我仍然无法准确理解什么在哪里,什么在做什么。这是我到目前为止:

I have a script that sets a set number of usernames, and then for each username, runs a fetch request to twitches API endpoint to get the Json information for each user. I then wanted to put that information into an array for later use, and found out I had to use promises, which I never worked with before. I read through this: https://developers.google.com/web/fundamentals/primers/promises and this: https://github.com/domenic/promises-unwrapping/blob/master/docs/states-and-fates.md and I read Felix Kling response here: How do I return the response from an asynchronous call? and I'm still having trouble understanding exactly what goes where and what does what. This is what I have so far:

var users = ["ESL_SC2", "OgamingSC2", "cretetion", "freecodecamp", "storbeck", "habathcx", "RobotCaleb", "noobs2ninjas"]

var arr = [];

var headers = {
  'Client-Id': 'xxxxxxxxxxx'
}

var promise = new Promise(function usersJson(callback) {
  for (i = 0; i < users.length; i++) {
    var url = "https://api.twitch.tv/helix/users?login=" + users[i];
    fetch(url, {headers})
    .then(function(response) {
      return response.json();
    })
    .then(function(myJson) {
      arr.push(myJson);
    })
    callback(arr);
  };
})

promise.then(function(result) {
  console.log(result);
})

从我的理解,这应该贯穿每个端点,将数据推送到我的数组变量,然后一旦整个事情完成它应该用我的promise变量调用'then'的东西console.log我的数组。我得到的只是一个空白数组,我真的不确定我做错了什么。如果我在arr.push(json)之后放入console.log(arr),我会返回8个数组,每个数组都有下一个响应主体,所以我知道这个调用正常,我只是无法得到它坚持我的阵列。

and from what I understand, this should be running through each endpoint, pushing the data to my array variable, and then once the whole things is "fulfilled" it should call the 'then' thing with my promise variable to console.log my array. All I get is a blank array and I'm really not sure what I'm doing wrong. If I put the console.log(arr) in after the arr.push(json), I get 8 arrays returned, each with the next response body tacked on, so I know the call is working, I just can't get it to stick in my array.

推荐答案

一种可以帮助你在承诺中多思考的方法是,一旦你做出承诺 - 你仍然可以获得数据,而你仍然处于承诺之地。在您的示例中,您将从 fetch 承诺中获取数据。这意味着您只能使用 fetch 承诺内的数据。请注意:

One way that may help you to think more in promises is that once you're in promise-land you can only get the data while you're still in promise-land. In your example, you're getting the data from the fetch promise. That means that you can only use that data from inside of the fetch promise. Notice here:

.then(function(myJson) {
  arr.push(myJson);
})
callback(arr);

arr.push 你在哪里构建数组的是里面的承诺,但是回调(arr)之外。由于你不再在承诺范围内,你无法获得数据。

The arr.push where you're building the array is inside the promise, but callback(arr) is outside. Since you're not inside the promise anymore you can't get the data.

在你的情况下你也想要同时等待多个承诺,因为你正在获取数据来自多个来源。最好的方法是使用 Promise.all 和一系列承诺:

In your case you also want to wait on multiple promises simultaneously since you're fetching data from multiple sources at once. The best way to do this would be to use Promise.all and an array of promises:

const promise = Promise.all(users.map(user => {
    const url = `https://api.twitch.tv/helix/users?login=${user}`;
    return fetch(url, { headers })
    .then(function(response) {
      return response.json();
    });
}));

现在 promise.then 将为您提供访问权限所有承诺都解决后,数据的数组。您不需要推送到另一个数组, .map 将为您创建承诺数组。

Now promise.then will give you access to an array of the data once all the promises have resolved. You don't need to push to another array, the .map will create the array of promises for you.

您也可以使用 async / await 语法编写此语法更容易推理并且可能更清洁。

You can also write this using the async / await syntax which is easier to reason about and potentially cleaner.

const promise = Promise.all(users.map(async user => {
    const url = `https://api.twitch.tv/helix/users?login=${user}`;
    const response = await fetch(url, { headers });
    return response.json();
}));






顺便说一句,你只需要使用新Promise 使用未自行实现promise的库时。 fetch 已经返回一个Promise,所以当你调用它时,你已经收到了一个承诺,所以没有必要用新Promise包装它


By the way, you should only need to use new Promise when working with libraries that don't implement promises themselves. fetch already returns a Promise, so when you call it you're already getting a promise back so there's no need to wrap it with new Promise.

这篇关于我试图理解如何在javascript中使用promises,但我的脚本从不执行“Then”。的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-18 05:11