Javascript 如果记录还不存在,如何优雅地查询并创建它? 目标

Javascript 如果记录还不存在,如何优雅地查询并创建它? 目标,javascript,ember.js,Javascript,Ember.js,startChat(partner_profile)的目标是获取两个用户之间聊天的id,然后能够重定向到此聊天。 有两种不同的情况: 他们之间的聊天已经存在 a) partner\u profile是第一个参与者 b) partner\u profile是第二个参与者 首先需要创建他们之间的聊天 到目前为止我得到了什么 我知道如何获得上面列出的每一个案例的ID,但我不知道如何将它们结合起来。以下是我目前的代码: startChat(合作伙伴档案){ //案例1a this.get('store'

startChat(partner_profile)
的目标是获取两个用户之间聊天的id,然后能够重定向到此聊天。 有两种不同的情况:

  • 他们之间的聊天已经存在

    a)
    partner\u profile
    是第一个参与者

    b)
    partner\u profile
    是第二个参与者

  • 首先需要创建他们之间的聊天
  • 到目前为止我得到了什么 我知道如何获得上面列出的每一个案例的ID,但我不知道如何将它们结合起来。以下是我目前的代码:

    startChat(合作伙伴档案){
    //案例1a
    this.get('store').queryRecord('chat'{
    第一个参与者:partner\u profile.id
    }).然后(功能(聊天){
    let id=chat.get('id');
    onSaveSuccess(id);
    }).catch(函数(){
    });
    //案例1b
    this.get('store').queryRecord('chat'{
    第二个参与者:partner_profile.id
    }).然后(功能(聊天){
    let id=chat.get('id');
    onSaveSuccess(id);
    返回;
    }).catch(函数(){
    //**错误处理*
    });
    //案例2
    let chat=this.get('store').createRecord('chat'{
    第二名参与者:合作伙伴简介
    });
    让onSaveSuccess=(id)=>this.transitionRoute('chats.chat',id);
    chat.save()
    .然后(功能(成功){
    让id=success.get('id');
    onSaveSuccess(id);
    })
    .catch((错误)=>{
    //**错误处理*
    }
    });
    
    我如何合并这些案例? 现在真的很难看,因为每个案子都被执行了,当然有两个失败了。我怎么能做得更好呢?有没有一种方法可以一次获取或创建一个记录(就像Django中的记录)? 谢谢您的帮助:-)

    编辑:更具体 更具体地说,我有一个问题,找到一个好方法来检查聊天是否已经存在于我们的数据库中。请参见此示例:

       let existingChat =  this.get('store').queryRecord('chat', {
          first_participant: partner_profile.id
      }).catch(function(){
    
       });
      if(!existingChat){
        // ** check for case 1b and 2
      };
    

    在本例中,我首先查询商店中的聊天记录。商店返回我保存在
    existingChat
    中的承诺,当我想用
    if(!existingChat)
    检查聊天是否已经存在时,该承诺尚未解决

    我不知道我是否有足够的代码,但以下是我过去如何处理
    get\u或\u create

    var数据库=[];
    函数getOrCreate(rowId){
    var rowIndex=database.findIndex(r=>rowId==r.Id);
    如果(行索引<0){
    database.push({
    Id:rowId
    });
    返回数据库[database.length-1];
    }否则{
    返回数据库[rowIndex];
    }
    }
    var item1=getOrCreate(1);
    var item2=getOrCreate(2);
    var item3=getOrCreate(3);
    var item4=getOrCreate(1);
    
    控制台日志(第4项)因此,最好的方法是首先查询该聊天,然后在找不到该聊天时处理创建该聊天(404):

    基本上,这是一个概念,但是如果你需要创建两个聊天室,它可能会更复杂。在这种情况下,您可以使用“rsvp”中的
    all
    hash
    帮助程序

    import Route from '@ember/routing/route';
    import { hash } from 'rsvp';
    
    export default Route.extend({
      // params is { first_participant, second_participant }
      model(params) {
        return this.store.queryRecord('chat', params)
          .catch(() => {
            // a 404 from the server would trigger a catch
            return hash({
              chatA: this.store.createRecord('chat', { first_participant: params.first_participant }),
              chatB: this.store.createRecord('chat', { second_participant: params.second_participant })
            });
          });
      }
    });
    
    上面将您的
    模型设置为
    {chatA,chatB}
    。您需要如何实现承诺的复杂性还取决于后端API的复杂性。有时,这是一种让您知道您的API不是最好的API的气味


    另一个更优雅的解决方案是使用async/await。 查看本指南:

    Async/await在IMO黄金时段已经就绪。上面的示例如下所示:

    import Route from '@ember/routing/route';
    
    export default Route.extend({
      // params is { first_participant, second_participant }
      async model(params) {
        let chat;
    
        try {
          chat = await this.store.queryRecord('chat', params);
        } catch(e) {
          // a 404 from the server would trigger a catch
          chat = await this.store.createRecord('chat', params);
        }
    
        return chat;
      }
    });
    
    这允许您以同步的方式编写异步代码,从而更易于编写和理解

    要开始使用上述内容,您需要修改
    ember cli build.js
    文件,就像上面的博客文章所指定的那样,即

    let app = new EmberApp(defaults, {
      // Add options here
      babel: {
        includePolyfill: true
      }
    });
    

    有关更多详细信息,我推荐这篇深入的文章

    以下是根据@knownasilya的建议重新组织的代码:

    getChatFirstParticipant().then(transitionToChat)
        .catch(() => {
          getChatSecondParticipant().then(transitionToChat)
             .catch(() => {
               createChat(partner_profile).then(transitionToChat)
                 .catch((error) => {
                   // ** error handling** 
                 });
         });
    

    谢谢你的回答!遗憾的是,你的回答对我没有帮助,但这是我的责任。我应该更具体地描述我的问题。我不知道我可以在if中插入什么(检查对象是否已经存在)。余烬存储返回一个承诺,因此如果(!existingChat)
    不起作用,则让existingChat=this.get('store').queryRecord(…)。我将扩展我的问题。我不需要创建两个不同的聊天。我只需要以两种不同的方式查询现有聊天(因为聊天伙伴可以保存为
    第一个参与者
    第二个参与者
    )。你是对的,API在这里有点麻烦,但是我继承了这段代码,现在修改它需要花费太多的时间。谢谢你,它为我工作了!现在我有了结构良好的代码@Whiterose我已经更新了我的答案,添加了另一个更优雅的解决方案。谢谢你的更新!我刚看到,抱歉耽搁了。我在研究答案时偶然发现了
    wait
    ,但没有使用它,因为如果我理解正确,它在Ember中还没有得到官方支持。此外,我还需要能够支持较旧的浏览器(在您提供的深入文章中指出,从10月17日起,仅支持流行浏览器的最后两个版本)。但这让我充满希望,在未来,我们将不再需要如此丑陋的捕获链^^^^使用babelPolyfill,您不必担心浏览器兼容性,因为它将代码更改为所有当前浏览器都支持的格式。
    getChatFirstParticipant().then(transitionToChat)
        .catch(() => {
          getChatSecondParticipant().then(transitionToChat)
             .catch(() => {
               createChat(partner_profile).then(transitionToChat)
                 .catch((error) => {
                   // ** error handling** 
                 });
         });