简体   繁体   English

ES6 - Promise.all在Promise.resolve中

[英]ES6 - Promise.all within a Promise.resolve

I'm using ecmascript 6 and am trying to execute a Promise.all() within a Promise.resolve() together in my API. 我正在使用ecmascript 6并尝试在我的API中一起在Promise.resolve()执行Promise.all()

Here's my code: 这是我的代码:

import jwt from "jsonwebtoken";
import Database from "../../../util/Database";
import send from "../../../util/send";

var updatePosition = function(organizationId, positionId, positionTitle) {
  let updatedPosition = {
    organization_id: organizationId,
    title: positionTitle
  };
  return Database.connection.query('UPDATE positions SET ? WHERE id=?', [updatedPosition, positionId]);
}

var unLinkUserToPosition = function(positionId) {
  return Database.connection.query('UPDATE users SET position_id=NULL WHERE position_id=?', positionId);
}

var linkUserToPosition = function(positionId, userId) {
  return Database.connection.query('UPDATE users SET position_id=? WHERE id=?', [positionId, userId]);
}

var getPositionAndCommittees = function(positionId) {
  return Promise.all([getPosition(positionId), getCommittees(positionId)]).then(formatJSON);
}

var getPosition = function(positionId) {
  return Database.connection.query('SELECT \
    p.id as position_id, \
    p.title as position_title, \
    u.id as user_id, \
    u.facebook_UID, \
    u.email, \
    u.first_name, \
    u.last_name, \
    u.phone, \
    u.semester_joined, \
    u.year_joined, \
    u.thumbnail_photo_URL, \
    u.cover_photo_URL \
    FROM positions p \
    LEFT JOIN users u ON p.id=u.position_id \
    WHERE p.id=? \
    ORDER BY p.id ASC', positionId);
}

var getCommittees = function(positionId) {
  return Database.connection.query('SELECT \
    c.id as committee_id, \
    c.title as committee_title, \
    u.id as chairmen_user_id, \
    u.thumbnail_photo_URL as chairmen_thumbnail_photo_URL, \
    u.first_name as chairmen_user_first_name, \
    u.last_name as chairmen_user_last_name \
    FROM committees c \
    LEFT JOIN users u ON c.chairmen_id=u.id \
    WHERE c.position_id=? ORDER BY c.title ASC', positionId);
}

var formatJSON = function(results) {
  let positionResult = results[0][0];
  let committeesResult = results[1];
  let position = {
    id: positionResult.position_id,
    title: positionResult.position_title,
    user: {
      id: positionResult.user_id,
      facebookUID: positionResult.facebook_UID,
      email: positionResult.email,
      firstName: positionResult.first_name,
      lastName: positionResult.last_name,
      phone: positionResult.phone,
      semesterJoined: positionResult.semester_joined,
      yearJoined: positionResult.year_joined,
      thumbnailPhotoURL: positionResult.thumbnail_photo_URL,
      coverphotoURL: positionResult.cover_photo_URL
    },
    committees: committeesResult
  };

  return position;
}

module.exports = function(req, res) {
  let token = req.headers['bearer-authorization'];
  let tokenSecret = ENV.API_SECRET
  let decodedToken = jwt.verify(token, tokenSecret);

  let organizationId = 1
  let positionId = req.params.positionId;
  let positionTitle = req.body.title;
  let positionUserId = req.body.userId;

  Promise.resolve(updatePosition(organizationId, positionId, positionTitle))
    .then(unLinkUserToPosition(positionId))
    .then(linkUserToPosition(positionId, positionUserId))
    .then(getPositionAndCommittees(positionId))
    .then(send.success(res))
    .catch(send.failure(res));
};

Side Note: I'm using promise-mysql for my database queries, which means that when I return Database.connection.query() , it's actually returning a new Promise 旁注:我正在使用promise-mysql进行数据库查询,这意味着当我返回Database.connection.query() ,它实际上返回了一个新的Promise


Here's what the send.success and send.failure functions look like: 这是send.successsend.failure函数的样子:

var send = {
  success: function(response) {
    return function(data) {
      response.status(200).json(data);
    };
  },
  failure: function(response) {
    return function(error) {
      var statusCode = error.statusCode || 500;

      if (statusCode === TEMPORARY_REDIRECT && error.body && error.body.value) {
          response.status(200).json(error.body.value);
          return;
      }

      console.error(error.stack);

      response.status(statusCode).json({
        message: error.message
      });
    };
  }
}

Heres the order I'm trying to get my functions to execute: 下面是我试图让我的函数执行的顺序:

  1. updatePosition updatePosition
  2. unLinkUserToPosition unLinkUserToPosition
  3. linkUserToPosition linkUserToPosition
  4. getPositionAndCommittees - This function calls Promise.all with getPosition and getCommittees and is supposed to call formatJSON as soon as getPosition() and getCommittees() finish executing and return the formatted JSON Data getPositionAndCommittees - 这个函数用getPositiongetCommittees调用Promise.all,并且一旦getPosition()和getCommittees()完成执行并返回格式化的JSON数据,就应该调用formatJSON
  5. send.success - This just outputs the JSON that should be returned from formatJSON send.success - 这只输出应该从formatJSON返回的JSON

The way it's executing right now is that the data returned from linkUserToPosition is being returned as the data in the send.success function, which means that the Promise.resolve is not waiting for getPositionAndCommittees to finish executing the Promise.all . 它现在正在执行的方式是从linkUserToPosition返回的数据作为send.success函数中的数据返回,这意味着Promise.resolve不等待getPositionAndCommittees完成执行Promise.all

Here's what the output looks like: 这是输出的样子:

{
  "fieldCount": 0,
  "affectedRows": 1,
  "insertId": 0,
  "serverStatus": 2,
  "warningCount": 0,
  "message": "(Rows matched: 1  Changed: 0  Warnings: 0",
  "protocol41": true,
  "changedRows": 0
}

Any suggestions on how I can accomplish what I'm trying to do would be greatly appreciated! 任何有关如何完成我正在尝试做的建议都将不胜感激!

I think the problem is that several functions are immediatly started and not only after the previous steps completed. 我认为问题是几个功能立即启动,而不仅仅是在前面的步骤完成之后。

Assuming this call chain: 假设这个调用链:

updatePosition(organizationId, positionId, positionTitle)
.then(unLinkUserToPosition(positionId))
.then(linkUserToPosition(positionId, positionUserId))
.then(getPositionAndCommittees(positionId))
.then(send.success(res))
.catch(send.failure(res));

This means the asynchronous functions updatePosition , unLinkUserToPosition , linkUserToPosition and getPositionAndCommittees will all be immediately started. 这意味着异步函数updatePositionunLinkUserToPositionlinkUserToPositiongetPositionAndCommittees都将立即启动。 The send functions too, but as these return a function which will be executed later it's no problem. send函数也是如此,但是当这些函数返回一个稍后将执行的函数时,它没有问题。 This means the functions execute immediatley and the resulting promise is assigned to .then() of the previous function - which makes no sense because then accepts a function (that might return a promise), and not a promise. 这意味着函数执行immediatley并将结果的promise分配给前一个函数的.then() - 这没有任何意义,因为它接受一个函数(可能返回一个promise),而不是一个promise。 What you need is: 你需要的是:

updatePosition(organizationId, positionId, positionTitle)
.then(updatePositionResult => unLinkUserToPosition(positionId))
.then(unLinkUserToPositionResult => linkUserToPosition(positionId, positionUserId))
.then(linkUserToPositionResult => getPositionAndCommittees(positionId))
.then(send.success(res))
.catch(send.failure(res));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM