【问题标题】:How can I get all Objects from parse server by an array of objectIDs?如何通过 objectID 数组从解析服务器获取所有对象?
【发布时间】:2018-07-05 17:08:50
【问题描述】:

我的第二个问题与我的第一个 question 有关。答案只是帮助我更多地了解我的问题。

我的情况:

我在 parseplattform 中有一个表格,用于存储我的用户照片。用户应该能够删除选定的那些。所以我在每张照片下都做了一个复选框,它会返回 picID。 所以下一步是在我的表格中找到所有选定的图片并“销毁”它们。

这是我的代码片段,用于查找所选图片:

  var inputs = document.querySelectorAll("input[type='checkbox']");

  for(var i = 0; i < inputs.length; i++) {
    if(inputs[i].checked == true){
      var imgForDelPromise = new Promise(function (resolve) {
        userPics_query.get(inputs[i].id, {
          success: function(picForDelete) {
            alert(picForDelete.id);
            resolve(picForDelete);
           },
           error: function(picForDelete, error) {
             alert("Error: " + error.code + " " + error.message);
           }
         });
      });
    }
  }

我的问题:

如果我从 12 张图片中选择第 1、5 和 8 张图片,我希望我也会取回第 1、5 和 8 张图片的 ID 但是我总是得到最后一个与我选择的项目一样多。在本例中为 3 乘以 8。

就像我在第一个问题中建议的那样,我用承诺尝试过,但没有帮助。

所以我问了谷歌并得到了this,但它也没有帮助我。

我希望你能理解我的问题和问题,并希望你能帮助我。

也许有一种更简单的方法,例如 query.equalTo(),我可以传递一个包含不同元素的数组并返回一个包含不同对象的数组。但我还没有找到。

谢谢。

更新:

问题仍然存在,我尝试再详细说明一下。 例如:

var ids = Array.from(document.querySelectorAll("input[type='checkbox']"))
.filter( //only checked inputs
    function(input) { return input.checked; }
).map( //map to a promise
    function(input) {
        return input.id;
    }
);

console.log(ids);

ids.forEach(function(id) {
    userPics_query.get(id)
    .then(function(picObject) {
        console.log(picObject.id);
    })
    .then(function(error) {
        console.log(error);
    });
});

我试图通过您的回答构建的内容给了我以下日志:

Array [ "x2WSASwKWI", "NuhRXja0PL" ]
NuhRXja0PL
NuhRXja0PL

我的问题: 我不知道如何遍历数组并为每个元素返回来自服务器的请求,因为每个循环都首先出现 THEN 请求,我无法以正确的顺序获取它。 我错过了什么?

通过使用Promise.all(promises),我传递了完整的数组,但query.get 一次只能处理一个字符串!

更新 2:

功能

query.get("xWMyZ4YEGZ", {
  success: function(gameScore) {
    // The object was retrieved successfully.
  },
  error: function(object, error) {
    // The object was not retrieved successfully.
    // error is a Parse.Error with an error code and message.
  }
});

来自parseplattform.org

【问题讨论】:

  • 更新了我的答案以显示当时如何处理一个 ID,但我建议不要这样做,而是尝试使用 userPics_query.get 解决问题

标签: javascript parse-platform


【解决方案1】:

我不确定您发布的代码是否是给您带来问题的实际代码。循环中的变量i 应该递增,因为它不用于异步回调(传递给new Promise 的函数会立即执行)。

但是;当您将输入用作数组时,确实给您带来问题的代码可以解决,过滤掉未检查的那些,然后将它们映射到承诺:

var inputs = Array.from(document.querySelectorAll("input[type='checkbox']"));
Promise.all(
  inputs.filter(//only checked inputs
    function(input){return input.checked; }
  ).map(//map to a promise
    function(input){
      console.log("calling get with id:",input.id);
      //removed the new Promise wrap because the get function
      //  returns a promise
      return (new Parse.Query(SomeThing)).get(input.id);
    }
  )
)
.then(
  function(deleted){ console.log("deleted:",deleted); },
  function(error){console.error("something went wrong:",error); }
);

由于问题显然来自 userPics_query.get 并且未在问题中提供,因此您可以通过当时处理 id 来解决问题。你可以这样做:

Array.from(document.querySelectorAll("input[type='checkbox']"))
.filter(//only checked inputs
    function(input){return input.checked; }
).reduce(//only start the next if current is finished
  function(p,input){
    console.log("calling get with id:",input.id);
    return p.then(
      all=>
        userPics_query.get(input.id)
        .then(item=>all.concat([item]))
    );
  },
  Promise.resolve([])
)
.then(
  function(deleted){ console.log("deleted:",deleted); },
  function(error){console.error("something went wrong:",error); }
);

最好继续使用Promise.all 并尝试找出userPics_query.get 有什么问题,我敢打赌它是异步代码中使用的共享全局可变依赖项。

【讨论】:

  • 感谢您的回答。是的,这是我的实际代码,但有点短。我测试了你的答案并得到以下结果: 0: Object { className: "Photo", _objCount: 45, id: "NuhRXja0PL" } 1: Object { className: "Photo", _objCount: 48, id: "NuhRXja0PL" } 所以问题仍然存在,因为两个对象具有相同的 ID。
  • @AlexImZug 更新了答案,确保所有 id 在输入中设置正确,如果设置正确,请确保您的 userPics_query.get 返回正确的对象。
  • 这是一个不同的输出,userPics_query.get 给了我一个不同的输出,因为这个命令在我的循环之后执行,因为它是异步的,我的循环是为了快速执行它。这是我获得 x 倍相同 ID 的方式。
  • calling get with id: x2WSASwKWI; calling get with id: NuhRXja0PL; Array [ "x2WSASwKWI", "NuhRXja0PL" ]; resoled id: x2WSASwKWI resolved with: NuhRXja0PL; resoled id: NuhRXja0PL resolved with: NuhRXja0PL;
  • 好答案。我建议@AlexImZug 也注意封装更多使用函数的建议。我更新了我的答案以强调 + 样板解析查询 + 一些关于复选框的 jquery 建议
【解决方案2】:

没有必要创建一个promise,因为查询函数会返回它们自己的promise。换句话说,在你的代码中,所有这些......

userPics_query.get(someParam, { success : successFn, error : errorFn })

可能会被这些替换...

userPics_query.get(someParam).then(successFn, errorFn)

无论你在 Promise 创建中包装了第一个表单,你都应该删除它并使用第二个表单。 一般来说,为小型、可测试的工作构建函数。

将其应用于您的代码,构建一个函数以返回一个承诺,以获取给定 id 的用户图片...

// note - OP should substitute real collection and prop names
function userPicWithId(inputId) {
    var query = new Parse.Query("MyUserPicCollection");
    query.equalTo("myUserPicIdProperty", inputId);
    return query.get(inputsId);
}

构建一个函数以从选中的复选框中返回一个 id 数组(从 here 借来的想法)...

// something like this, but OP should test
function checkedIds() {
    return $(":checkbox:checked").map(() => this.id).get();
}

这为我们提供了两个简单的、可测试的功能。而且使用起来也很简单,如下...

let promises = checkedIds().map(anId => userPicWithId(anId);

使用 Promise.all 运行所有的 Promise...

Promise.all(promises).then(results => console.log(results));

所有这些建议也适用于您之前的问题。一旦掌握了使用正确封装的 Promise 和逻辑的窍门,事情就会变得简单得多。

【讨论】:

  • 应该用Array.from(queryselector).filter或更具体的查询选择器过滤掉未选中的复选框:querySelectorAll('input:checked')可能不需要包装userPics_query.get但我不是确定它来自哪里以及它是否正确使用(似乎是它没有做 OP 认为它做的事情)
  • @danh 我收到了TypeError: inputs.map is not a functionOnce you get the hang of using promises properly, things get much simpler.我相信它,我认为我非常接近它,但问题仍然存在于两种解决方案中。
  • @AlexImZug map 是 Array.prototype 的一个方法。 querySelectorAll 不返回一个数组,但因为它返回一个 nodelist 虽然文档没有提到;这是可迭代的,因此您可以使用Array.from。与此解决方案唯一不同的是,对userPics_query.get 的调用没有包含在new Promise 中,因为它已经返回了一个承诺。我更新了我的答案以反映这一点。
【解决方案3】:

我已经看到,最高效的做法是在单个查询中查询所有 id,然后按照您的需要操作它们。

export const getUsers = async (ids: string[]) => {
  const userQuery = new Parse.Query(Parse.User);
  userQuery.containedIn('objectId', ids);

  const data = await userQuery.find({ useMasterKey: true });

  const map = data.reduce((acc, item) => ({
      ...acc,
      [item.id]: item,
  }), {} as { [id: string]: Parse.User });

  return map;
};

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多