Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/89.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何转换为使用Promises和Q库_Javascript_Jquery_Promise_Q - Fatal编程技术网

Javascript 如何转换为使用Promises和Q库

Javascript 如何转换为使用Promises和Q库,javascript,jquery,promise,q,Javascript,Jquery,Promise,Q,我们的应用程序正在增长,我们的客户端脚本需要进行重构,使其更干净、更精简、更易于维护。我尝试使用一个小模块a利用Q库进行承诺链接 如您所见,我需要将一些返回值从初始函数传递回承诺链的其余部分。 有人能帮我理解我需要做什么才能保证第一个函数正常返回吗?然后解释链条 以下是我的出发点: var promise = new Q.Promise(generateMoveRequest) .then(function (id) { var woNum = 12345;

我们的应用程序正在增长,我们的客户端脚本需要进行重构,使其更干净、更精简、更易于维护。我尝试使用一个小模块a利用Q库进行承诺链接

如您所见,我需要将一些返回值从初始函数传递回承诺链的其余部分。 有人能帮我理解我需要做什么才能保证第一个函数正常返回吗?然后解释链条

以下是我的出发点:

var promise = new Q.Promise(generateMoveRequest)
    .then(function (id) {
       var woNum = 12345;
       return layoutInit(woNum, id, true);
    }).then(function (result) {
        if (result) {
          return moveRequestInit(result, true);
        } else { 
          throw new Error('Template not loaded');
        }
    }).catch(function (err) {
        console.log(err);
    });
生成移动请求:

布局初始化:

GenerateMoverRequest函数将执行,但链将不再继续。不,那么执行和布局永远不会被调用

我正在使用Q库,但有些示例似乎忽略了如何启动/创建承诺或将初始函数转换为承诺


有人能解释一下我这里的错误,或者给我一个清晰的例子吗?

承诺的jQuery实现不遵循a+标准,所以最好使用Q

promise必须接收一个带有两个参数的函数——resolve和reject——它们也是函数——记住Javascript是一种函数语言。成功时必须调用resolve函数,错误时必须调用reject函数。传递给这些函数的任何内容都将在then和catch回调中可用

长话短说,像这样重写代码:

var generateMoveRequest = function (resolve, reject) {
  $.ajax({
    method: "GET",
    url: window.contextPath + '/api/settings/getjson',
    data: {name: "the_name"},
    success: function (data) {
      if (data.length) {
        var id = $.parseJSON(data).Parent;
        resolve(id);
      } else {
        reject({message: 'Data not received'})
      }
    },
    error: function (xhr, textStatus, errorThrown) {
      reject({message: errorThrown})
  }
  });
}

var promise = new Q.Promise(generateMoveRequest)
    .then(function (id) {
       var woNum = 12345;
       return layoutInit(woNum, id, true);
    }).then(function (result) {
        if (result) {
          return moveRequestInit(result, true);
        } else {
          throw new Error('Template not loaded');
        }
    }).catch(function (error) {
      console.log(error.message)
    });
稍后编辑-请参阅代码片段以了解承诺的工作原理:

// any number of params
function willPerformAnAsyncOperationAndReturnAPromise(firstParam, secondParam, thirdParam) {
  var promise = new Q.Promise(function (resolve, reject) { // always resolve & reject
    // perform an async operation, like waiting one second
    window.setTimeout(function () {
      if (firstParam !== 0) {
        // if the 1st param is not 0, it's a success
        resolve ({
          first: firstParam,
          second: secondParam,
          third: thirdParam
        })
      } else {
        reject({message: 'The first param must not be null'})
      }
    }, 1000)
  })

  return promise
}

willPerformAnAsyncOperationAndReturnAPromise(1, 2, 3)
  .then(function (data) {
    console.log(data)
  })
  .catch(function (error) {
    console.log(error)
  })

willPerformAnAsyncOperationAndReturnAPromise(0, 2, 3)
  .then(function (data) {
    console.log(data)
  })
  .catch(function (error) {
    console.log(error)
  })
一些问题:

您的函数generateMoverRequest应该返回一些东西:$。ajax返回一个承诺,它有一个then方法,所以您可以直接返回它

您不需要创建新的承诺,因为generateMoverRequest会返回一个。这样你就避免了麻烦

建议代码:

generateMoveRequest: function () {
    return $.ajax({
        method: "GET",
        url: window.contextPath + '/api/settings/getjson',
        data: {name: "the_name"},
    }).then(function (data) {
        if (data.length) {
            var id = $.parseJSON(data).Parent;                                          
            return id;
        }
    }).catch(function (xhr, textStatus, errorThrown) {
        console.log("xhr: ", xhr);
        return null;
    })
}

var promise = generateMoveRequest()
    .then(function (id) {
        var woNum = 12345;
        return layoutInit(woNum, id, true);
    }).then(function (result) {
        if (result) {
           return moveRequestInit(result, true);
        } else { 
           throw new Error('Template not loaded');
        }
    }).catch(function (err) {
        console.log(err);
    });

您的函数GenerateMoverRequest应该返回一些内容:$。ajax返回一个承诺,它有一个then方法,所以您可以直接返回它。@trincot我让它返回一个值=>ID,它是成功回调的返回值,而不是函数GenerateMoverRequest的返回值。谢谢。非常感谢!我现在意识到,任何Promise函数都必须显式地具有resolve和reject。现在更有意义了。在那之后,它就像一个符咒一样工作。它工作了,但它使用了,因为$.ajax已经是一个承诺。请注意,从jQuery 3.0开始,jQuery的承诺实现是。如果我有一个承诺函数,但有两个参数,该怎么办?例如:generateMoverRequestParam1,param2。它是否需要包装到承诺和链?@加密在您的情况下,GenerateMoverRequest是包装在承诺中的异步操作,将始终采用2个参数。我在原始答案中添加了一个解释,以便您更好地理解@如果初始承诺不是A+,则它不是反模式。最好现在就用兼容的类型包装它,因为它以后很容易重构。downvoter可以留下评论让我知道我错过了什么吗?
// any number of params
function willPerformAnAsyncOperationAndReturnAPromise(firstParam, secondParam, thirdParam) {
  var promise = new Q.Promise(function (resolve, reject) { // always resolve & reject
    // perform an async operation, like waiting one second
    window.setTimeout(function () {
      if (firstParam !== 0) {
        // if the 1st param is not 0, it's a success
        resolve ({
          first: firstParam,
          second: secondParam,
          third: thirdParam
        })
      } else {
        reject({message: 'The first param must not be null'})
      }
    }, 1000)
  })

  return promise
}

willPerformAnAsyncOperationAndReturnAPromise(1, 2, 3)
  .then(function (data) {
    console.log(data)
  })
  .catch(function (error) {
    console.log(error)
  })

willPerformAnAsyncOperationAndReturnAPromise(0, 2, 3)
  .then(function (data) {
    console.log(data)
  })
  .catch(function (error) {
    console.log(error)
  })
generateMoveRequest: function () {
    return $.ajax({
        method: "GET",
        url: window.contextPath + '/api/settings/getjson',
        data: {name: "the_name"},
    }).then(function (data) {
        if (data.length) {
            var id = $.parseJSON(data).Parent;                                          
            return id;
        }
    }).catch(function (xhr, textStatus, errorThrown) {
        console.log("xhr: ", xhr);
        return null;
    })
}

var promise = generateMoveRequest()
    .then(function (id) {
        var woNum = 12345;
        return layoutInit(woNum, id, true);
    }).then(function (result) {
        if (result) {
           return moveRequestInit(result, true);
        } else { 
           throw new Error('Template not loaded');
        }
    }).catch(function (err) {
        console.log(err);
    });