Javascript承诺链接问题(Ember)

时间:2016-07-19 20:13:24

标签: javascript asynchronous ember.js promise

我正在尝试将文件上传到远程服务器,在该服务器上获取该文件的路径,然后将其保存在我自己的API的记录中。超过一半的时间,代码崩溃,因为returnedNewFile未定义(虽然我在之前的.then()函数中检查了console.log(newFile)并且它总是一个promise对象。可能导致这种行为的原因是什么? returnedNewFile有时候是null / undefined?我正在使用Django REST + django-rest-json-api + ember.js 2.6,这个代码在一个组件的javascript文件中。提前谢谢!

  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)
  });

编辑:这是uploadFile()的代码(waterbutler是外部服务器上使用的文件服务器的名称(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));
}

这是_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));
}

1 个答案:

答案 0 :(得分:1)

  

超过一半的时间,代码崩溃,因为returnedNewFile是   undefined(虽然我在之前检查过console.log(newFile)   .then()函数,它始终是一个promise对象。可能是什么   导致这种行为?

Promise会在调用.then()时解析其他Promise。因此,虽然您可以从promise 1的函数返回一个字符串,并且您将在其.then()调用中获得相同的字符串,但如果您在其函数内返回另一个Promise,则情况也是如此。在给出.then结果之前,它会将第二个承诺解析为具体值。

因此,如果您拨打newFile.then(function(newFileResult) { ...,那么newFileResult将与您在上述代码中获得的returnedNewFile参数相同。为什么这个库的承诺有时会带有undefined值,这超出了我的范围。

编辑:不太明白这个评论,所以举个例子。我有一个名为getText(str)的函数,它异步检索该字符串。

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"
});

根据对承诺的某种理解,str2将是Promise而不是string;但事实并非如此。它看到它取回了Promise,而不是“价值”,并在链接.then()电话之前等待它。即使getText(“def”)在3秒内回来,它也会等待第二次调用3秒钟,然后给我们.then()结果。