2016-04-05 13 views
0

ich habe ein kleines Problem, dieses Skript funktioniert perfekt, mit einem Problem, das „runTenant“ Methode ist nicht ein Versprechen der Rückkehr (die von „all()“ muss die LösungKnoten Rückkehr BluebirdJS Versprechen

Dieser Code.:

Promise.resolve(runTenant(latest)).then(function() { 
    end(); 
}); 

fordert diesen Code:

function runTenant(cb) { 
    return new Promise(function() { 
    //global var 
    if (!Tenant) { 
     loadCoreModels(); 
     Tenant = bookshelf.core.bs.model('Tenant'); 
    } 

    new Tenant().fetchAll() 
     .then(function(tenants) { 

     if (tenants.models.length == 0) { 
      return; 
     } else { 
      async.eachSeries(tenants.models, function(tenant, next) { 

      var account = tenant.attributes; 
      Promise.resolve(db_tenant.config(account)).then(function(knex_tenant_config) { 
       if (knex_tenant_config) { 
       db_tenant.invalidateRequireCacheForFile('knex'); 
       var knex_tenant = require('knex')(knex_tenant_config); 
       var knex_pending = cb(knex_tenant); 
       Promise.resolve(knex_pending).then(function() { 
        next(null, null); 
       }); 
       } else { 
       next(null, null); 
       } 
      }); 

      }); 
     }; 
     }); 
    }); 
} 

der Code von runTenant richtig funktioniert aber es Stände und können nicht zum "end()", weil das Versprechen von "runTenant (spätestens)" isn‘ t sein gelöst werden.

Als ob es nicht offensichtlich wäre, bin ich schrecklich bei Versprechungen. Arbeitet immer noch daran, meinen Kopf um sie herum zu bekommen.

Vielen Dank für jede Hilfe/Richtung!

+0

in der Konsole Fehler? – JordanHendrix

Antwort

1

Sie nicht den Promise Konstruktor überhaupt hier verwenden sollten (und im Grunde auch nicht anderswo), selbst wenn Sie es zum Laufen gebracht hätten, wäre es ein antipattern. Sie haben dieses Versprechen nie gelöst - beachten Sie, dass die resolve argument zu Promise Konstruktor Rückruf ist eine sehr unterschiedliche Funktion als Promise.resolve.

Und Sie sollten nicht die async Bibliothek verwenden, wenn Sie eine leistungsstarke Versprechen Bibliothek wie Bluebird zur Hand haben.

Als ob es nicht offensichtlich wäre, bin ich schrecklich bei Versprechungen.

Vielleicht wollen Sie einen Blick auf meine rules of thumb zum Schreiben von Versprechen Funktionen.

Hier ist, was Ihre Funktion sollte wie folgt aussehen:

function runTenant(cb) { 
    //global var 
    if (!Tenant) { 
    loadCoreModels(); 
    Tenant = bookshelf.core.bs.model('Tenant'); 
    } 
    return new Tenant().fetchAll().then(function(tenants) { 
    // if (tenants.models.length == 0) { 
    // return; 
    // } else 
    // In case there are no models, the loop iterates zero times, which makes no difference 
    return Promise.each(tenants.models, function(tenant) { 
     var account = tenant.attributes; 
     return db_tenant.config(account).then(function(knex_tenant_config) { 
     if (knex_tenant_config) { 
      db_tenant.invalidateRequireCacheForFile('knex'); 
      var knex_tenant = require('knex')(knex_tenant_config); 
      return cb(knex_tenant); // can return a promise 
     } 
     }); 
    }); 
    }); 
} 
+0

Danke @Bergi, das hat perfekt funktioniert. Ich werde auch deine Faustregeln durchlesen, wie ich es noch klarer verstehen möchte ... was genau passiert. Ich hatte den Eindruck, dass der erste Code, der das runTenant aufruft, weil es in einer Resolve-Methode war, dass jedes Versprechen, das zu ihm zurückkehrte, gelöst wird. Das Wichtigste, was ich bei deinem Vorschlag bemerke (was perfekt funktionierte), ist, dass du alle Versprechungen zuvor gelöst hast die Rückkehr. Ben oben, empfahl dies auch. Danke euch beiden! – sol

+0

Ah, ja, vergessen, eine Bemerkung über Ihre Verwirrung mit "Entschlossenheit" aufzunehmen. Fühlen Sie sich frei, über jeden Teil zu kommentieren, den Sie nicht verstehen, ich werde das klären. – Bergi

+0

Ich bin nicht einmal sicher, ob Sie das brauchen 'Promise.resolve (db_tenant.config (account))' - was gibt 'config (...)' zurück? – Bergi

0

Sie müssen alle verschachtelten Versprechen zurückgeben. Ich kann diesen Code nicht ausführen, also ist das kein Problem. Aber hoffentlich hilft es Ihnen zu verstehen, was fehlt.

function runTenant(cb) { 
    //global var 
    if (!Tenant) { 
     loadCoreModels(); 
     Tenant = bookshelf.core.bs.model('Tenant'); 
    } 

    return new Tenant().fetchAll() //added return 
     .then(function (tenants) { 

      if (tenants.models.length == 0) { 
       return; 
      } else { 
       var promises = []; //got to collect the promises 
       tenants.models.each(function (tenant, next) { 

        var account = tenant.attributes; 
        var promise = Promise.resolve(db_tenant.config(account)).then(function (knex_tenant_config) { 
         if (knex_tenant_config) { 
          db_tenant.invalidateRequireCacheForFile('knex'); 
          var knex_tenant = require('knex')(knex_tenant_config); 
          var knex_pending = cb(knex_tenant); 
          return knex_pending; //return value that you want the whole chain to resolve to 
         } 
        }); 
        promises.push(promise); //add promise to collection 
       }); 
       return Promise.all(promises); //make promise from all promises 
      } 
     }); 
} 
+0

Auch sieht es so aus, als ob Sie eingebaute Promises verwenden. Ich empfehle dringend, stattdessen [Bluebird] (http://bluebirdjs.com/) zu verwenden. Es hat eine Methode wie Promise.each() eingebaut, die das vereinfacht. Es hat auch ein hilfreiches Warnsystem, das Sie über einige Fehler hier gewarnt hätte. – Ben

0

Ihre Versprechen in runTenant Funktion wird nie gelöst. Sie müssen resolve oder reject Funktion aufrufen Versprechen zu beheben:

function runTenant() { 
    return new Promise(function(resolve, reject) { 
    // somewhere in your code 
    if (err) { 
     reject(err); 
    } else { 
     resolve(); 
    } 
    }); 
}); 

Und Sie sollten nicht cb in runTenant Funktion übergeben, verwenden Versprechen Kette:

runTenant() 
.then(latest) 
.then(end) 
.catch(function(err) { 
    console.log(err); 
}); 
Verwandte Themen