Возвращение обещаний вверх по цепочке функций - PullRequest
0 голосов
/ 31 марта 2020

Ниже приведена структура кода, который я написал. Я пытаюсь загрузить несколько файлов на сервер, используя ajax, и как только все будет выполнено, выполните какое-то действие.

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

}

К сожалению, это не работает, как я ожидал. Массив results - это не массив обещаний, а массив неопределенных. Я новичок в Javascript обещаниях, поэтому любая помощь будет признательна.

РЕДАКТИРОВАТЬ: чтобы ответить на комментарий о возможности молчаливого возврата, я публикую фактический код для func2 (слегка измененный):

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

  }
}

Ответы [ 2 ]

0 голосов
/ 31 марта 2020

Ваш блок else ничего не возвращает:

...
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
}

Не обманывайте себя оператором return в анонимной функции. Он возвращает анонимную функцию, а не 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);   -------------------'
    }
  )

Это было бы более очевидно, если переписать код без использования анонимных функций:

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 !!
  }
}

Один из способов обойти это это преобразовать его в обещание:

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

Конечно, в зависимости от того, как протекает ваш журнал ошибок c, вы можете захотеть обернуть обещание на более высоком уровне. Это просто иллюстрирует быстрое исправление.

0 голосов
/ 31 марта 2020

Вам нужно вернуть новое обещание в КАЖДОЙ функции!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...