JavaScript 动态承诺

JavaScript Dynamic Promises

我试图通过玩 swapi.dev 来了解 JS 中的 promises 是如何工作的。我想创建一个动态的承诺链(不使用 async/await),但它没有为我提供任何结果。特别是,背后的想法是获取给定人员的所有姓名(例如 Luke Skywalker)并将它们转储到控制台中。

谁能帮帮我?我错过了什么?

提前致谢。

"use strict";

const request = require("request-promise");
const BASE_URL = "http://swapi.dev/api";

var currentPromise = Promise.resolve();

callApiPromise(`${BASE_URL}/people/1`).then((data) => {
  console.log("Getting vehicles' URLs");
  const vehicles_URL = data["vehicles"];

  console.log("Starting looping through URLs");
  for (let i = 0; i < vehicles_URL.length; i++) {
    console.log(`i=${i}, vehicle_URL=${vehicles_URL[i]}`);
    currentPromise = currentPromise.then(function () {
      console.log(".. getting vehicle name");
      return getVehicleName[vehicles_URL[i]];
    });
  }
});

function getVehicleName(url) {
  callApiPromise(url).then((vehicle_data) => {
    var arrVehicleData = new Array();
    arrVehicleData.push(vehicle_data);
    console.log(arrVehicleData.map((vehicle) => vehicle.name));
  });
}

function callApiPromise(url) {
  return new Promise((resolve, reject) => {
    callApi(url, (err, data) => {
      if (err) {
        reject(err);
        return;
      }
      resolve(data);
    });
  });
}

function callApi(url, callback) {
  request
    .get(url)
    .then((response) => {
      const json = JSON.parse(response);
      callback(null, json);
    })
    .catch((err) => {
      callback(err, null);
    });
}

一些问题:

  • getVehicleName
  • 中缺少 return 语句
  • getVehicleName[vehicles_URL[i]] 中的语法问题(应该是括号)
  • 由于获取车辆名称的承诺是独立的,您不会将它们链接起来,而是使用 Promise.all
  • arrVehicleData 永远只有一个元素。没有理由在使用它的地方使用数组。

您在使用 request.get 时也采取了错误的方法。底部函数将 API 从 Promise-API 转换为回调 API,仅在其上方的函数中执行相反的操作(从回调到 promise)。你应该跳过回调层并坚持承诺:

"use strict";

const request = require("request-promise");
const BASE_URL = "http://swapi.dev/api";

getJson(`${BASE_URL}/people/1`).then(data => {
  return Promise.all(data.vehicles.map(getVehicleName));
}).then(vehicleNames => {
  console.log(vehicleNames);
  // Continue here...
});

function getVehicleName(url) {
  return getJson(url).then(vehicle => vehicle.name);
}

function getJson(url, callback) {
  return request.get(url).then(JSON.parse);
}

最后,您不应该再使用 request-promise,因为 request-promise 所依赖的请求模块已经 deprecated

getVehicleName 没有 return 承诺。相反,它调用一个承诺,即在它被解析时,调用它的 for 循环已经从调用堆栈中删除。

这是承诺链的示例:

const promise = new Promise(resolve => resolve(1))
const promise1 = Promise.resolve(2)
const methodReturnPromise = () => new Promise(resolve => resolve(3))

promise.then(firstPromiseData => {
  // do something with firstPromiseData
  console.log(firstPromiseData)
  return promise1
}).then(secondPromiseData => {
  // do something with secondPromiseData
  console.log(secondPromiseData)
  return methodReturnPromise()
}).then(thirdPromiseData => { 
  // do something with thirdPromiseData
  console.log(thirdPromiseData)
})