简体   繁体   中英

Returning promises up a function chain

Below is the structure of some code that I have written. I am attempting to load a number of files to a server using ajax and once all are complete, do some action.

function func1(items){
 const results = []
 for (let i=0; i<items.length; i++) {
    results[i] = func2();
 }

 Promise.all(results).then(response => some_action())
}

function func3(params) {

  return new Promise((resolve, reject) => {
    //ajax call here and resolve/reject
  })
}

function func2(){

 if(stuff){
   return func3(some_params);
 } else {
   return func3(other_params);   
 }

}

Unfortunately, it is not working as I expected. The array results is not an array of promises, but an array of undefined. I am new to Javascript promises, so any help would be appreciated.

EDIT: to respond to the comment about the possibility of a silent return, I post the actual code for func2 (lightly modified):

function func2(item, id, id2, top_level, path){

  if(item.isFile){
    item.file(function(file) {
      if(file.name.substring(file.name.lastIndexOf('.')+1) === "docx"){
        file = new File([file], file.name, {
          type: "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
        })
      }
      if(file.name !== "desktop.ini"){
        let url = 'url'
        return func3(file, id, url, "", false);
      }
    });
  } else {

      window.parent.ipcRenderer.send('zip-folder', path);

      window.parent.ipcRenderer.on('zipped', (event, buffer) => {
        var zipped_file = new File([buffer], item.name + ".zip", {
          type: "application/zip"
        })
        let url = "/url"
        return func3(zipped_file, id, url, id2, true);
      })

  }
}

您需要在每个函数中返回新的 Promise !

Your else block does not return anything:

...
else {

  window.parent.ipcRenderer.send('zip-folder', path);

  window.parent.ipcRenderer.on('zipped', (event, buffer) => {
    var zipped_file = new File([buffer], item.name + ".zip", {
      type: "application/zip"
    })
    let url = "/url"
    return func3(zipped_file, id, url, id2, true);
  })

  // silently returns undefined
}

Don't be fooled by the return statement in the anonymous function. It returns the anonymous function, not func2 :

  window.parent.ipcRenderer.on('zipped',                         return this
                                         (event, buffer) => {  <----------.
      var zipped_file = new File([buffer], item.name + ".zip", {          |
        type: "application/zip"                                           |
      })                                                                  |
      let url = "/url"                                                    |
      return func3(zipped_file, id, url, id2, true);   -------------------'
    }
  )

This would be more obvious if you rewrite your code without using anonymous functions:

function func4(id, url, id2) {
  return function (event, buffer) {
    var zipped_file = new File([buffer], item.name + ".zip", {
      type: "application/zip"
    })
    let url = "/url"
    return func3(zipped_file, id, url, id2, true);
  }
}

function func2(item, id, id2, top_level, path){

  if(item.isFile){
    item.file(function(file) {
      if(file.name.substring(file.name.lastIndexOf('.')+1) === "docx"){
        file = new File([file], file.name, {
          type: "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
        })
      }
      if(file.name !== "desktop.ini"){
        let url = 'url'
        return func3(file, id, url, "", false);
      }
    });
  } else {

      window.parent.ipcRenderer.send('zip-folder', path);

      window.parent.ipcRenderer.on('zipped', func4(id, url, id2))

      // no return statement !!
  }
}

One way to get around it is to convert it into a promise:

return new Promise((ok,fail) => {
  window.parent.ipcRenderer.on('zipped', (event, buffer) => {
    var zipped_file = new File([buffer], item.name + ".zip", {
      type: "application/zip"
    })
    let url = "/url"
    ok(func3(zipped_file, id, url, id2, true));
  })
});

Of course, depending on how your error logic flows you may want to wrap the promise at a higher level. This merely illustrates a quick fix.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM