无法停止兑现承诺

时间:2016-09-08 13:16:25

标签: javascript node.js es6-promise

我有一个复杂的javascript函数,里面有promises。

这是我的代码:

var chunkProjectList = function(list, project, accounts) {
  return new Promise((resolve, reject) => {
    // init delta
    let delta = 5
    if ((accounts.length * delta) > list.length ) {
      delta = (list.length / accounts.length)
    }
    // init chunked list
    let chunkedList = []
    for (let i = 0; i < accounts.length; i++) {
      chunkedList.push([])
    }
    // loop on all users
    for (let i = 0; i < list.length; i++) {
      isInBlacklist(list[i], project.id)
      .then(() => { // current user is in the blacklist
        ProjectModel.deleteElementFromList(project.id, list[i])
        if (i === list.length - 1) {
          // no screen_names available, cu lan
          return resolve(chunkedList) 
        }
      })
      .catch(() => { // we continue
        let promises = []
        for (let j = 0; j < accounts.length; j++) {
          promises[j] = FollowedUserModel.getFollowedUserByScreenName(list[i], accounts[j].id)
        }
        // we checked a screen_name for all accounts
        Promise.all(promises)
        .then((rows) => {
          for (let k = 0; k < rows.length; k++) {
            if (rows[k][0].length === 0 && chunkedList[k].length < delta && list[i] !== '') {
              console.log('we push')
              chunkedList[k].push(list[i])
              break
            }
            console.log('we cut (already followed or filled chunklist)')
            if (k === rows.length - 1) {

              // determine if is cancer screen_name or just filled chunklists
              for (let l = 0; l < chunkedList.length; l++) {
                if (chunkedList[l].length < delta) {
                  console.log('we cut because nobody wants ya')   
                  ProjectModel.deleteElementFromList(project.id, list[i])
                  ProjectModel.addElementToBlackList(project.id, list[i])
                }
                if (l === chunkedList.length - 1) {
                  // you are all filled, cu lan
                  return resolve(chunkedList)
                  break
                }
              }
            }
          }
          if (i === list.length - 1) {
          // no screen_names available, cu lan
            over = 1
            return resolve(chunkedList)
          }
        })
      })
    }
  })
}

我的程序在用户名列表上循环,并尝试在帐户之间共享,每个帐户都有一个名为“delta”的限制

例如: 我的列表包含1000个用户名,delta为100,我有4个帐户 预期的结果是一个数组数组,包含每个数组,100个用户名。

chunkedList(array)=&gt; (数组1:长度100,数组2:长度100 ......)

我遇到的问题如下:

当达到所有chunkedList数组的delta时,我只想退出这个函数,并停止里面的每一个工作,甚至是运行的promises。就在我'返回解决(chunkedList)'时。

但该计划继续运行,这对于表演来说是一个真正的问题。

我知道很难理解代码。感谢

1 个答案:

答案 0 :(得分:0)

我很难理解您的代码要完成的任务。但是,看起来您可以将代码拆分为几个单独的promise函数。这有助于清晰,并允许您停止执行。无法测试您的代码,主要问题似乎是由您的主循环引起的。在您的代码中,您有以下内容:

.then(() => {
    ....
    return resolve(chunkedList);
}

此处的“return”语句仅从内部.then()调用返回,而不是从您的主Promise返回。因此,您的主循环将继续在整个数组上执行其所有代码。从本质上讲,您的循环似乎将继续修改您的主Promise的已解析值,并且在整个循环完成之前永远不会返回。

我的建议是将主循环内容拆分为一个单独的方法,将列表作为参数。此方法将返回Promise。使用该方法,您可以使用主循环创建Promise.all(),然后添加.catch()方法。当您拒绝其中一个方法调用(因此没有在Promise.all数组的其余部分中完成其余的promise)时,将发生catch()方法。

如果我的上述建议没有任何意义,我道歉。我想尽快写这个。总之,如果您可以将方法的不同步骤拆分为返回自己的promise的方法,则可以非常有效地使用promises,允许您并行地链接,执行多个任务,和/或按顺序执行任务。