Javascript在循环中承诺

时间:2018-01-14 12:58:28

标签: javascript node.js es6-promise

我有一个名为_problemFunction的函数,它将一个数组myList作为参数。对于myList中的每个项目,我调用一个函数_myFunction_myFunction返回一个承诺。如果_myFunction返回解析我列表中的任何项目,我想从_problemFunction返回解析。如果_problemFunction对myList中的所有项目返回拒绝,我想从_myFunction返回拒绝。下面是场景的代码块:

_problemFunction = (myList) => {
  return new promise((resolve, reject) => {
    myList.forEach(listItem => {
      _myFunction(listItem).then(pass => {
        //Resolve when _myFunction returns resolve with any listitem argument  
      }).catch(fail => {
        //reject only if _myfunction returns rejects for all the listitems
      })
    })
  })
}

4 个答案:

答案 0 :(得分:1)

看看Promise.all() https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all

 let request = data.map((i) => {
    return new Promise((resolve, reject) => {
       if(i < 1) {
          reject('value to low')
       }
        resolve(i);
    }); });
    return  Promise.all(data) });

答案 1 :(得分:1)

    _problemFunction = (myList) => {
  return new promise((resolve, reject) => {
    const errs = [];
    myList.forEach(listItem => {
      _myFunction(listItem)
      .then(resolve)
      .catch(fail => {
        errs.push(fail);
        errs.length === myList.length ? reject(errs) : '';
      })
    })
  })
}

答案 2 :(得分:1)

据我所知,你只想拒绝所有的承诺,所以你必须知道拒绝是否与运行拒绝回调的数组长度相同,如下所示:

    return new promise((resolve, reject) => {
   let rejectCount = 0
   let resolved = false
   for(let listItem of myList){
      _myFunction(listItem).then(pass => {
        //Resolve when _myFunction returns resolve with any listitem argument
        if(!resolved){ 
         resolved = true
         resolve(pass) 
        }
      }).catch(fail => {
        //reject only if _myfunction returns rejects for all the listitems
        rejectCount++
        if(rejectCount === myList.length) {
          reject(fail)
        }
      })
      if(resolved) break
   }
})

如果您的列表为空或未定义的边缘情况,您可以在for循环之前添加此检查:

if(!myList || myList.length === 0) {
    reject(new Error('list is empty or undefined')
    return
}

答案 3 :(得分:0)

这取决于您是要并行还是串联地执行列表中的所有项目:

解决第一个解决并拒绝所有系列错误的项目:

//serial resolve on first resolved item
_problemFunction = (myList,failed=[]) => {
  if(myList.length===0){
    return Promise.reject(failed);
  }
  return _myFunction(myList[0])
  .catch(
    //try it again with the next item
    err=>_problemFunction(myList.slice(1),failed.concat([err]))
  )
}

一次尝试所有并首先返回任何结果但拒绝所有失败的结果(除非您的列表为空,否则它将以空列表失败)

//parallel resolve on first resolved item reject when all reject
_problemFunction = (myList,failed=[]) => {
  if(failed.length===0){
    myList = myList
    .map(([item,index])=>
      [
        index,
        _myFunction(item)
        .catch(err=>Promise.reject([err,index]))
      ]
    );
  }
  if(myList.length===0){
    return Promise.reject(failed);
  }
  return Promise.race(
    myList.map(([i,p])=>p)
  )
  .catch(
    ([err,index])=>//an error remove the failed item and try again
      _problemFunction(
        myList.filter(([i,p])=>i!==index),
        failed.concat([err])
      )
  )
}