【问题标题】:How to convert this promise object into an array with the result如何将此promise对象转换为带有结果的数组
【发布时间】:2020-05-15 08:20:55
【问题描述】:

所以我调用 tmdb API 来获取所选电影的电影详细信息,但该响应不包含演员的演员详细信息,所以我使用第一个响应返回的 id 调用他们的其他 api 来获取演员详情。

这是行动


export const loadNewReleases = () => {
  const posterBaseUrl = "http://image.tmdb.org/t/p/w185";
  let hasUserSaved;
  return async (dispatch, getState) => {
    // console.log("????????", getState());
    try {
      const response = await fetch(
        `https://api.themoviedb.org/3/trending/all/day?api_key=${config.TMDB_API_KEY}`
      );

      if (!response.ok) {
        throw new Error("failed response");
      }

      const resData = await response.json();
      console.log(resData);

      const getCredits = async (index) => {
        let response, creditsData;
        try {
          response = await fetch(
            `https://api.themoviedb.org/3/movie/${resData.results[index].id}?api_key=${config.TMDB_API_KEY}&language=en-US&append_to_response=credits`
          );
          creditsData = await response.json();
          // console.log("credits", creditsData);
        } catch (err) {
          throw new Error(err);
        }

        const castMembers = [];
        const length = creditsData.credits.cast.length;

        for (let i = 0; i < length; i++) {
          castMembers.push(
            new Cast(
              creditsData.credits.cast[i].id,
              creditsData.credits.cast[i].character,
              creditsData.credits.cast[i].name,
              posterBaseUrl + creditsData.credits.cast[i].profile_path
            )
          );
        }

        console.log(castMembers);

        return castMembers;
      };

      const LoadedNewReleases = [];
      const length = resData.results.length;

      for (let i = 0; i < length; i++) {
        // let credits;
        hasUserSaved = getState().UserMovies.userMovies.find(
          (userMovie) => userMovie.id === resData.results[i].id.toString()
        );
        // let cast = getCredits(i).then((cast) => cast);
        // console.log("CAST", cast);
        LoadedNewReleases.push(
          new Movie(
            resData.results[i].id.toString(),
            resData.results[i].media_type === "movie"
              ? resData.results[i].title
              : resData.results[i].name,
            posterBaseUrl + resData.results[i].poster_path,
            resData.results[i].media_type === "movie"
              ? resData.results[i].release_date
              : resData.results[i].first_air_date,
            getCredits(i).then((cast) => cast),
            // cast,
            resData.results[i].overview,
            resData.results[i].vote_average,
            "",
            hasUserSaved ? hasUserSaved.location : ""
          )
        );
      }

      dispatch({ type: LOAD_NEW_RELEASES, new_releases: LoadedNewReleases });
    } catch (err) {
      console.log(err);
    }
  };
};

这是减速器


switch(action.type){

    case LOAD_NEW_RELEASES:
      return {
        ...state,
        new_releases: action.new_releases,
      };

}

这就是我发送动作的方式:selectedMovie.cast


     selectedMovie = movies.find((movie) => movie.id === selectedMovieId);
    console.log("selectedMovie", selectedMovie);

        <FlatList
          showsHorizontalScrollIndicator={false}
          horizontal={true}
          data={selectedMovie.cast}
          renderItem={(itemData) => (
            <CastMember
              castName={itemData.item.name}
              posterUrl={itemData.item.profileUrl}
              character={itemData.item.character}
            />
          )}
        />

这是日志

在加载应用程序时 我收到以下黄色警告

[未处理的承诺拒绝:TypeError:未定义不是对象(评估'creditsData.credits.cast')] * 在 getCredits 中存储/动作/MoviesAction.js:77:25 - tryCatch 中的 node_modules/regenerator-runtime/runtime.js:45:44 - 调用中的 node_modules/regenerator-runtime/runtime.js:274:30 - tryCatch 中的 node_modules/regenerator-runtime/runtime.js:45:44 - 调用中的 node_modules/regenerator-runtime/runtime.js:135:28 - PromiseImpl.resolve.then$argument_0 中的 node_modules/regenerator-runtime/runtime.js:145:19 - tryCallOne 中的 node_modules/promise/setimmediate/core.js:37:14 - setImmediate$argument_0 中的 node_modules/promise/setimmediate/core.js:123:25 - _callTimer 中的 node_modules/react-native/Libraries/Core/Timers/JSTimers.js:146:14 - _callImmediatesPass 中的 node_modules/react-native/Libraries/Core/Timers/JSTimers.js:194:17 - node_modules/react-native/Libraries/Core/Timers/JSTimers.js:458:30 在 callImmediates * [本机代码]:callImmediates 中的 null - __callImmedates 中的 node_modules/react-native/Libraries/BatchedBridge/MessageQueue.js:407:6 - __guard$argument_0 中的 node_modules/react-native/Libraries/BatchedBridge/MessageQueue.js:143:6 - __guard 中的 node_modules/react-native/Libraries/BatchedBridge/MessageQueue.js:384:10 - __guard$argument_0 中的 node_modules/react-native/Libraries/BatchedBridge/MessageQueue.js:142:17 * [本机代码]:flushedQueue中的null * [本机代码]:invokeCallbackAndReturnFlushedQueue中的null

[未处理的承诺拒绝:TypeError:未定义不是对象(评估'creditsData.credits.cast')] * 在 getCredits 中存储/动作/MoviesAction.js:77:25 - tryCatch 中的 node_modules/regenerator-runtime/runtime.js:45:44 - 调用中的 node_modules/regenerator-runtime/runtime.js:274:30 - tryCatch 中的 node_modules/regenerator-runtime/runtime.js:45:44 - 调用中的 node_modules/regenerator-runtime/runtime.js:135:28 - PromiseImpl.resolve.then$argument_0 中的 node_modules/regenerator-runtime/runtime.js:145:19 - tryCallOne 中的 node_modules/promise/setimmediate/core.js:37:14 - setImmediate$argument_0 中的 node_modules/promise/setimmediate/core.js:123:25 - _callTimer 中的 node_modules/react-native/Libraries/Core/Timers/JSTimers.js:146:14 - _callImmediatesPass 中的 node_modules/react-native/Libraries/Core/Timers/JSTimers.js:194:17 - node_modules/react-native/Libraries/Core/Timers/JSTimers.js:458:30 在 callImmediates * [本机代码]:callImmediates 中的 null - __callImmedates 中的 node_modules/react-native/Libraries/BatchedBridge/MessageQueue.js:407:6 - __guard$argument_0 中的 node_modules/react-native/Libraries/BatchedBridge/MessageQueue.js:143:6 - __guard 中的 node_modules/react-native/Libraries/BatchedBridge/MessageQueue.js:384:10 - __guard$argument_0 中的 node_modules/react-native/Libraries/BatchedBridge/MessageQueue.js:142:17 * [本机代码]:flushedQueue中的null * [本机代码]:invokeCallbackAndReturnFlushedQueue中的null

并在调度上述动作时 我明白了:

selectedMovie Movie {
  "cast": Promise {
    "_40": 0,
    "_55": Array [
      Cast {
        "character": "Tim Morris",
        "id": 60950,
        "name": "David Spade",
      },
      Cast {
        "character": "Missy",
        "id": 591834,
        "name": "Lauren Lapkus",
      },
      Cast {
        "character": "Camille",
        "id": 175585,
        "name": "Candace Smith",
      },
      Cast {
        "character": "Julia",
        "id": 49001,
        "name": "Sarah Chalke",
      },
      Cast {
        "character": "Melissa",
        "id": 60952,
        "name": "Molly Sims",
      },
      Cast {
        "character": "Jack Winstone",
        "id": 25879,
        "name": "Geoff Pierson",
      },
      Cast {
        "character": "Nate",
        "id": 32907,
        "name": "Nick Swardson",
      },
      Cast {
        "character": "Jess",
        "id": 60959,
        "name": "Jackie Sandler",
      },
      Cast {
        "character": "Rich",
        "id": 1573273,
        "name": "Chris Witaske",
      },
      Cast {
        "character": "Vanilla Ice",
        "id": 17338,
        "name": "Vanilla Ice",
      },
      Cast {
        "character": "Calvin Sr.",
        "id": 5621,
        "name": "John Farley",
      },
      Cast {
        "character": "Bus Woman",
        "id": 1922821,
        "name": "Lori Pelenise Tuisano",
      },
      Cast {
        "character": "Komante",
        "id": 60949,
        "name": "Rob Schneider",
      },
      Cast {
        "character": "Gary",
        "id": 1170011,
        "name": "Leati Joseph Anoa'i",
      },
      Cast {
        "character": "Toki Dum Dum",
        "id": 198149,
        "name": "Bobby Lee",
      },
    ],
    "_65": 1,
    "_72": null,
  },
  "id": "582596",
  "language": "",
  "location": "",
  "plot": "A guy meets the woman of his dreams and invites her to his company's corporate retreat, but realizes he sent the invite to the wrong person.",
  "posterUrl": "http://image.tmdb.org/t/p/w185/A2YlIrzypvhS3vTFMcDkG3xLvac.jpg",
  "ratings": 6.1,
  "title": "The Wrong Missy",
  "year": "2020-05-13",
}

看到 cast 对象有一个 promise 对象,并且它在 _55 上有一个数组,这就是实际结果。 还有是什么原因导致它们仅在我执行第二次 api 调用时才出现。

小吃链接

Snack Link

当应用启动时,点击趋势下的任何项目>查看日志。

【问题讨论】:

  • 在 expo 上做一个问题并将其与问题联系起来。
  • 添加零食项目的链接

标签: javascript json reactjs rest react-native


【解决方案1】:

你的问题是:

getCredits(i).then((cast) => cast)

你实际上并没有等待这个 Promise 的结果,你只是在一个 cast 对象应该是的地方传递了一个 Promise。

您实际上需要将 Movie 的创建制作成视频到 then 调用,然后等待所有这些完成并用包含这些新承诺的 awaitPromise.all 解包。

以最简单的方式可能是这样的:

const LoadedNewReleases = [];
const length = resData.results.length;

for (let i = 0; i < length; i++) {
  // let credits;
  hasUserSaved = getState().UserMovies.userMovies.find(
    (userMovie) => userMovie.id === resData.results[i].id.toString()
  );
  // let cast = getCredits(i).then((cast) => cast);
  // console.log("CAST", cast);
  LoadedNewReleases.push(
    getCredits(i).then(
      (cast) =>
        new Movie(
          resData.results[i].id.toString(),
          resData.results[i].media_type === "movie"
            ? resData.results[i].title
            : resData.results[i].name,
          posterBaseUrl + resData.results[i].poster_path,
          resData.results[i].media_type === "movie"
            ? resData.results[i].release_date
            : resData.results[i].first_air_date,
          cast,
          // cast,
          resData.results[i].overview,
          resData.results[i].vote_average,
          "",
          hasUserSaved ? hasUserSaved.location : ""
        )
    )
  );
}

dispatch({ type: LOAD_NEW_RELEASES, new_releases: await Promise.all(LoadedNewReleases) });

如果您希望 hasUserSaved 逻辑尽可能晚地运行,您可能还想将其移到那里,但我不太确定它在做什么,所以将它留在原处。

【讨论】:

  • 实际上这不起作用,因为 cast 对象来自 creditsData 响应对象,而其他对象来自 resData 响应对象。你能想到别的吗?这将是一个很大的帮助,我被困在那里一段时间了。
  • 没有真正的理由这不应该工作。这是合并两个响应对象的问题。上面的cast 变量取自getCredits 的结果( creditsData 值),而其余变量取自resData
  • 这可能不是因为我认为演员必须提取到另一个对象数组中,因为它具有不同的结构并且是数组的大对象。
  • 我不太确定您的意思(如何提取),但我将此更改复制并粘贴到您的博览会链接中,该应用程序似乎运行良好:snack.expo.io/unNYF6x0T
  • 除了问题之外,如果我选择了 selectedMovie.cast._55 ,它会起作用,因为 promise 对象具有具有结果的 _55 属性,是否建议遵循此解决方法?
猜你喜欢
  • 2013-04-19
  • 1970-01-01
  • 2021-01-28
  • 2018-10-29
  • 1970-01-01
  • 1970-01-01
  • 2022-01-04
  • 2019-04-10
相关资源
最近更新 更多