代码之家  ›  专栏  ›  技术社区  ›  JDT

嵌套回调中的Node.js Promises in Promises in Promises不解析

  •  1
  • JDT  · 技术社区  · 6 年前

    下面的代码无法解析。 f2解决,所以我不会添加该代码,它是f1我有一个问题。

    我调用函数,它会到达最内部,如果,它调用函数“find”,它执行函数 findId ,这样就可以很好地返回Id,然后执行 editId 但它不能解决 document replaced +当上下文日志出现时,我知道它达到了。

    预期行为:

    这应该会回到最高的承诺和达到 context.done() 但事实并非如此

    这可能是一个简单的问题,就我把新的承诺等方面,但我已经挣扎了一段时间的结构。

    谢谢你的洞察力。

    module.exports = function (context, req) {
        var documentUrl = xyz;
        client.readDocument(documentUrl, (err, a) => {
    
            var f1 = fun1(a,b,c);
            var f2 = fun2(a,b,c);
    
            Promise.all([f1, f2]).then(function(results){ //parallel
                context.log(results[0], results[1]);
                context.done();
            });
        });
    }
    
    function fun1 (a,b,c){
    if (a[0].stuff.length > 0) {
        var stuffArray = [];
        for (i = 0; i < a[0].stuff.length; i++) {
            if (a[0].stuff[i].morestuff !== null && a[0].stuff[i].otherstuff !== null) {
                if (a[0].stuff[i].Id== null) {
                var Id = a[0].id + '_' + i;
                    var find = findId (a, Id, function(res){
                        context.log ("findFeedback: found");
                                context.log(res);                            
                                editId(context, res);
                    });
                    stuffArray.push(find);                
                }
            } else {
                stuffArray.push(i + " shouldn't have Id");
            }    
        }
        return Promise.all(stuffArray);
    } else {
        return ('No stuff');
    }
    }
    function findId(a, Id, callback) {    
        var documentUrl = myUrl/id;
            client.readDocument(documentUrl, (err, result) => {
                if (err) {
                    if (err) {
                        return(err);
                    }
                } else {
                    callback(result);
                 }
            });
    }
    
    function editId(context, res) {
        return new Promise((resolve, reject) => {
        var documentUrl = myUrl/res.otherId;
            client.readDocument(documentUrl, (err, result) => {
                if (err) {
                    if (err.code == HttpStatusCodes.NOTFOUND) {
                        context.log('Post does not exist');
                        resolve('Post does not exist');
                    } else {
                        context.log(err);
                        resolve(err);
                    }
                } else {
                    context.log('Post exists');
                    // here i edit some stuff which works fine                            
                    client.replaceDocument(documentUrl, result, (err, result) => {
                    if(err) {
                        context.log(err);
                        resolve('Document replaced ' + false);
                    } else {
                        context.log('replaced document ' + result);
                        resolve('Document replaced ' + true);
                        // This is where my context log ends it does not resolve back up 
                    }
            });                
    
                 }
            });
        });
    };
    
    2 回复  |  直到 6 年前
        1
  •  2
  •   Dat Tran    6 年前

    这里的重点是使代码保持一致。

    我觉得你应该把所有的回调函数包装成Promise。这将使你的代码更干净,更容易,而不是成为一个意大利面。

    我没有足够的上下文来测试。所以我试着重构一下你的代码。希望对你有所帮助。

    findId函数应返回一个promise,而不是使用回调:

    function findId(Id) {
      return new Promise((resolve, reject) => {
        var documentUrl = myUrl / id;
        client.readDocument(documentUrl, (err, result) => {
          if (err) {
            reject(err);
          } else {
            resolve(result);
          }
        });
      });
    }
    

    在fun1函数中,for循环中有异步代码。它不会工作,因为异步代码不会等到有结果。所以我通过推送你需要调用的id来重构 findId 进入之内 stuffArr . 然后,我将这些id映射到promise函数的列表中 芬迪 . 通过这样做,我们可以使用Promise.all来等待所有承诺的实现。

    function fun1(a, b, c) {
      if (a[0].stuff.length > 0) {
        var stuffArray = [];
        for (i = 0; i < a[0].stuff.length; i++) {
          if (
            a[0].stuff[i].morestuff !== null &&
            a[0].stuff[i].otherstuff !== null
          ) {
            if (a[0].stuff[i].Id == null) {
              var Id = a[0].id + "_" + i;
              var promise = findId(Id)
                    .then(res => editId(context, res))
                    .catch(err => i + " Some error");
              stuffArray.push(promise);
            } else {
              // don't know what you want to do here
            }
          } else {
            stuffArray.push(i + " shouldn't have Id");
          }
        }
    
        return Promise.all(stuffFindPromises);
      } else {
        return Promise.resolve("No stuff");
      }
    }
    

    希望这有帮助。

        2
  •  0
  •   JDT    6 年前

    findId 要求 return new Promise((resolve,reject) => { }); 包裹着它。

    然后你可以打电话 editId 在内部 芬迪 并替换 callback(result) 具有 resolve(editId(context, result));

    之后更换 var find 在里面 fun1 具有 var find = findId (a, id) 并从 芬迪