Search code examples
javascriptreactjses6-promise

promise.resolve() in for loop return undefined


I've tried to get a tree node after search process. But it always return undefined.. here's the code.

const findOrder = (list, key) =>
  new Promise((resolve) => {
    for (let i = 0; i < list.length; i++) {
      // find node through key in tree
      if (list[i].key === key) {
        console.log(`================I got it!: `, list[i].children); // children[]
        resolve(list[i].children);
      }
      if (list[i].children) {
        findOrder(list[i].children, key);
      }
    }
  });

const setOrder = async() => {
  const orders = await findOrder(
    treeData,
    dropObj.classKind === "1" ? keyGen(dropObj.key) : dropObj.key
  );
  console.log(`==================siblings: `, orders); // undefined
};
setOrder();

what is the problem?


Solution

  • You did not resolve it here,

          // ...
          if (list[i].children) {
            findOrder(list[i].children, key);
          }
          // ...
    

    To let the outer Promise know when to resolve it, you should explicitly do it:

          // ...
          if (list[i].children) {
            findOrder(list[i].children, key).then(result => {
              // as resolve can only be called once,
              // do not call it if it doesn't found anything
              if (result) resolve(result)
            });
          }
          // ...
    

    This should work. However, this implementation has too many useless calls to 'resolve'. It's better to find the matched item directly and resolve it.

    Here is an example:

    const findOrder = function (list, key) {
      return new Promise((resolve, reject) => {
        resolve(find(list, key))
    
        function find (_list, key) {
          for (let i = 0; i < _list.length; i++) {
            if (_list[i].key === key) return _list[i].children
            if (_list[i].children) {
              const c = find(_list[i].children, key)  
              if (c) return c
            }
          }
          return undefined
        }
      })
    }