2016-07-19 14 views
0

Ich versuche, eine Datei auf einen Remote-Server hochladen, den Pfad für diese Datei auf diesem Server abrufen, und speichern Sie es dann in einem Datensatz auf meine eigene API. Über die Hälfte der Zeit stürzt der Code ab, da returnedNewFile nicht definiert ist (obwohl ich console.log (newFile) in der vorherigen .then() -Funktion überprüft habe und es immer ein Promise-Objekt ist. Was könnte dieses Verhalten verursachen? Was könnte verursachen? returnedNewFile manchmal null/undefiniert sein? ich verwende Django REST + django-rest-json-api + Ember.js 2,6, und dieser Code ist in einer JavaScript-Datei der Komponente. Vielen Dank im Voraus!Javascript Versprechen Verkettung Probleme (Ember)

store.findRecord('file', folderid).then(function(folder) { 
    var file = fileList.pop(); 
    var newFile = fm.uploadFile(folder, file.name, file); 
    return newFile; 

    }).then(function(returnedNewFile) { 
    var name = returnedNewFile.get('name'); 
    var path = returnedNewFile.get('path'); 
    var doc = store.createRecord('document', { 
     name: name, 
     path: path, 
    }); 
    console.log("doc: ", doc); 
    doc.save(); 
    return doc; 

    }).then(function(doc) { 
    console.log("hi number three"); 
    var grant = store.createRecord('grant', { 
     department: department, 
     number: number, 
     document: doc, 

    }); 
    grant.save(); 
    return grant; 

    }).then(null, function(error) { 
    console.log("Oops: " + error.message) 
    }); 

EDIT: Hier ist der Code für uploadFile() (waterbutler ist der Name des Dateiservers auf dem externen Server verwendet wird (link)):

uploadFile(folder, name, contents, options = {}) { 
    let url = folder.get('links').upload; 
    options.data = contents; 
    if (!options.query) { 
     options.query = {}; 
    } 
    options.query.name = name; 
    options.query.kind = 'file'; 

    let p = this._waterbutlerRequest('PUT', url, options); 
    return p.then(() => this._getNewFileInfo(folder, name)); 
} 

Und hier ist der Code für _getNewFileInfo:

/** 
* Get the `file` model for a newly created file. 
* 
* @method _getNewFileInfo 
* @private 
* @param {file} parentFolder Model for the new file's parent folder. 
* @param {String} name Name of the new file. 
* @return {Promise} Promise that resolves to the new file's model or 
* rejects with an error message. 
*/ 
_getNewFileInfo(parentFolder, name) { 
    let p = this._reloadModel(parentFolder.get('files')); 
    return p.then((files) => files.findBy('name', name)); 
} 
+0

Wäre 'fm.uploadFile()' nicht asynchron? Von welchem ​​Modul node.js stammt das, damit wir uns das Dokument ansehen können? – jfriend00

+0

[Hier ist] (https://github.com/CenterForOpenScience/ember-osf/blob/develop/addon/services/file-manager.js) ein Link zu der Datei-Manager (FM) -Klasse. 'fm.uploadFile()' ist asynchron, aber ich hatte den Eindruck, dass diese Art der Verkettung dafür verantwortlich ist. Klingt, als ob ich vielleicht weg wäre. – Cameron

+1

Es könnte immer eine "Promise" -Instanz sein, aber es könnte manchmal ein Versprechen sein, das mit "undefined" erfüllt. Zeigen Sie uns, was '_getNewFileInfo' tut. – Bergi

Antwort

1

Über die Hälfte der Zeit, die Code abstürzt, weil returnedNewFile nicht definiert ist (obwohl ich geprüft console.log (newFile habe) im vorherigen .then () Funktion und es ist immer ein Versprechensobjekt. Was könnte dieses Verhalten verursachen?

Versprechen lösen andere Promise beim Aufruf . Während Sie also eine Zeichenfolge aus der Funktion von Versprechen 1 zurückgeben können und dieselbe Zeichenfolge in ihrem Aufruf erhalten, gilt dies nicht, wenn Sie innerhalb ihrer Funktion ein anderes Versprechen zurückgegeben haben. Es wird stattdessen dieses zweite Versprechen auf einen konkreten Wert auflösen, bevor es ein .then Ergebnis gibt.

Also, wenn Sie newFile.then(function(newFileResult) { ... aufgerufen haben, dann newFileResult wäre das gleiche wie das, was Sie jetzt in den obigen Code als das returnedNewFile Argument bekommen. Warum die Versprechen dieser Bibliothek manchmal mit einem undefined Wert zurückkommen, ist mir ein Rätsel.

EDIT: Habe den Kommentar nicht ganz verstanden, also ein Beispiel. Ich habe eine Funktion namens getText(str), die diese Zeichenfolge asynchron abruft.

response1 = getText("abc").then(ignoredStr => { 
    return "def"; 
}); 

response2 = getText("abc").then(ignoredStr => { 
    return getText("def"); 
}); 

response1.then(function(str1) { 
    // "def" 
}); 

response2.then(function(str2) { 
    // "def" 
}); 

Unter einem gewissen Verständnis von Versprechungen, würde str2 ein Promise anstelle eines string sein; aber das ist nicht der Fall. Es sieht, dass es ein Versprechen, kein "Wert" zurückbekommt, und wartet darauf, bevor es den Anruf verkettet. Selbst wenn getText ("def") in 3 Sekunden zurückkommt, würde es 3 weitere Sekunden für den zweiten Anruf warten, bevor es uns ein .then() Ergebnis gibt.

+0

Wenn du dieses zweite Versprechen auflöst, meinst du damit gewaltsam, es sofort zu lösen oder zu warten, bis es sich natürlich löst? Ich entschuldige mich, wenn das eine dumme Frage ist. Immer noch versuchen, die Nuancen von Async herauszufinden. – Cameron

+0

@Cameron Ich habe ein Beispiel hinzugefügt, hoffentlich hilft das zu verstehen. – Katana314