Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/412.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中使用回调处理可选参数_Javascript_Node.js_Node Webkit - Fatal编程技术网

如何在javascript中使用回调处理可选参数

如何在javascript中使用回调处理可选参数,javascript,node.js,node-webkit,Javascript,Node.js,Node Webkit,这里sendMessage()函数已经编写,并且在没有FormData参数的所有模块中都得到了很好的使用(sendMessage(类型、url、方法、json、重试、cb)),但是对于文件上传,我们需要使用formData传递文件路径,而不改变其他所有功能。如果您希望支持的两种不同调用方案是: //request is a node module var request = require('request'); /** * send REST web service mess

这里sendMessage()函数已经编写,并且在没有FormData参数的所有模块中都得到了很好的使用(
sendMessage(类型、url、方法、json、重试、cb)
),但是对于文件上传,我们需要使用formData传递文件路径,而不改变其他所有功能。

如果您希望支持的两种不同调用方案是:

//request is a node module   
var request = require('request');
 /**
     * send REST web service message to server
     * @function sendMessage
     * @param {string} method - GET, POST, PUT, DELETE
     * @param {string} url - server URL
     * @param {object} json - The data to be send
     * @param {object} cb - callback function
     *@param{object}formData-The data related to file upload
     * @returns void
     */
    function sendMessage(type,url,method,json,retries,formData,cb){
        var options={
        url:url,
        formData:formData,
        json:true,
switch (method) {
    case 'get':
      request.get(options, cb);
      break;
    case 'post':
      envelope.token = json.token;
      envelope.package = json.package;
      options.body = envelope;
      request.post(options, cb);
      break;
    case 'put':
      envelope.package = json.package;
      envelope.token = json.token;
      options.body = envelope;
      request.put(options, cb);
      break;
    case 'delete':
      request.delete(options, cb);
      break;       
 }
这是:

sendMessage(type,url,method,json,retries,formData,cb)
而且,回调参数始终是必需的,然后,您可以这样做:

sendMessage(type,url,method,json,retries,cb)
 function sendMessage2(type,url,method,json,retries,formDataArg,cbArg) {
      // full implementation here with all arguments, formDataArg may be null
 }

 // original function here, calling signature unchanged
 function sendMessage(type,url,method,json,retries,cbArg) {
     // call new implementation with arguments in the right place
     return sendMessage2(type, url, method, json, retries, null, cbArg);
 }
正如其他人所说,当您获得这么多参数时,最好使用一个附加属性的选项对象。然后,将一些参数设置为可选参数就变得容易多了

您可能还会发现这一点很有用:


仅供参考,还有一种方法可以用更难输入的语言解决类似的问题。您将创建第二个函数,该函数接受额外的参数并将实现移到那里。然后,原来的函数就变成了一个shell,它用新参数的
null
调用新函数

function sendMessage(type,url,method,json,retries,formDataArg,cbArg) {
    var cb = cbArg, formData = formDataArg;
    // if we don't have a cb arg, then it must have been called with the
    // shorter form that doesn't have formData
    if (!cb) {
       cb = formDataArg;
       formData = null;
    }

    // continue rest of function using cb and formData as the symbols
    // for the last two arguments

    // ... other code here ...

}
虽然这可以工作并且不使用重载,但这是一次性的,因为您不想以sendMesage3、sendMessage4等结束。。。sendMessage2可能应该使用可扩展性更强的options对象,这样您就不会再被迫使用它了。然后,稍后当您有更多的灵活性时,您可以将较旧的代码切换到options对象,并完全摆脱整个two-API方案

可能是这样的:

sendMessage(type,url,method,json,retries,cb)
 function sendMessage2(type,url,method,json,retries,formDataArg,cbArg) {
      // full implementation here with all arguments, formDataArg may be null
 }

 // original function here, calling signature unchanged
 function sendMessage(type,url,method,json,retries,cbArg) {
     // call new implementation with arguments in the right place
     return sendMessage2(type, url, method, json, retries, null, cbArg);
 }

注意,我将回调排除在options对象之外,因为这使函数与典型的异步调用约定兼容,并使调用方的内联回调更易于编码。

如果要支持的两种不同调用方案是:

//request is a node module   
var request = require('request');
 /**
     * send REST web service message to server
     * @function sendMessage
     * @param {string} method - GET, POST, PUT, DELETE
     * @param {string} url - server URL
     * @param {object} json - The data to be send
     * @param {object} cb - callback function
     *@param{object}formData-The data related to file upload
     * @returns void
     */
    function sendMessage(type,url,method,json,retries,formData,cb){
        var options={
        url:url,
        formData:formData,
        json:true,
switch (method) {
    case 'get':
      request.get(options, cb);
      break;
    case 'post':
      envelope.token = json.token;
      envelope.package = json.package;
      options.body = envelope;
      request.post(options, cb);
      break;
    case 'put':
      envelope.package = json.package;
      envelope.token = json.token;
      options.body = envelope;
      request.put(options, cb);
      break;
    case 'delete':
      request.delete(options, cb);
      break;       
 }
这是:

sendMessage(type,url,method,json,retries,formData,cb)
而且,回调参数始终是必需的,然后,您可以这样做:

sendMessage(type,url,method,json,retries,cb)
 function sendMessage2(type,url,method,json,retries,formDataArg,cbArg) {
      // full implementation here with all arguments, formDataArg may be null
 }

 // original function here, calling signature unchanged
 function sendMessage(type,url,method,json,retries,cbArg) {
     // call new implementation with arguments in the right place
     return sendMessage2(type, url, method, json, retries, null, cbArg);
 }
正如其他人所说,当您获得这么多参数时,最好使用一个附加属性的选项对象。然后,将一些参数设置为可选参数就变得容易多了

您可能还会发现这一点很有用:


仅供参考,还有一种方法可以用更难输入的语言解决类似的问题。您将创建第二个函数,该函数接受额外的参数并将实现移到那里。然后,原来的函数就变成了一个shell,它用新参数的
null
调用新函数

function sendMessage(type,url,method,json,retries,formDataArg,cbArg) {
    var cb = cbArg, formData = formDataArg;
    // if we don't have a cb arg, then it must have been called with the
    // shorter form that doesn't have formData
    if (!cb) {
       cb = formDataArg;
       formData = null;
    }

    // continue rest of function using cb and formData as the symbols
    // for the last two arguments

    // ... other code here ...

}
虽然这可以工作并且不使用重载,但这是一次性的,因为您不想以sendMesage3、sendMessage4等结束。。。sendMessage2可能应该使用可扩展性更强的options对象,这样您就不会再被迫使用它了。然后,稍后当您有更多的灵活性时,您可以将较旧的代码切换到options对象,并完全摆脱整个two-API方案

可能是这样的:

sendMessage(type,url,method,json,retries,cb)
 function sendMessage2(type,url,method,json,retries,formDataArg,cbArg) {
      // full implementation here with all arguments, formDataArg may be null
 }

 // original function here, calling signature unchanged
 function sendMessage(type,url,method,json,retries,cbArg) {
     // call new implementation with arguments in the right place
     return sendMessage2(type, url, method, json, retries, null, cbArg);
 }

注意,我将回调排除在options对象之外,因为这使函数与典型的异步调用约定兼容,并使调用方的内联回调更易于编码。

创建一个新方法,该方法接受对象作为参数,它分析对象并决定是代理原始功能还是执行新需求

将原始方法标记为已弃用,并记录以使用新方法,时机成熟时,可以替换对原始方法的调用。当它们全部被替换时,重构新函数以删除代理,并在确定后删除旧方法

尝试从原始方法中提取尽可能多的功能,以保持代码干燥


如果可能,编写一个原始方法和新方法都可以通过的测试。

创建一个新方法,该方法接受对象作为参数,分析对象并决定是代理原始函数还是执行新要求

将原始方法标记为已弃用,并记录以使用新方法,时机成熟时,可以替换对原始方法的调用。当它们全部被替换时,重构新函数以删除代理,并在确定后删除旧方法

尝试从原始方法中提取尽可能多的功能,以保持代码干燥


如果可能的话,编写一个原始方法和新方法都可以通过的测试。

有这么多参数,我认为您应该使用一个对象来代替。是的,您是正确的,但它已经以这种方式构建,并在所有其他模块中使用。现在改变是不可能的。我需要一个不影响其他模块的解决方案。您可能希望阅读这篇文章,其中还包括可选参数。为什么函数定义中formData参数需要在cb参数之前?有这么多参数,我认为您应该使用单个对象。是的,您是正确的,但是,它已经以这种方式构建,并在所有其他模块中使用。现在改变是不可能的。我需要一个不影响其他模块的解决方案。您可能希望阅读这篇文章,其中还包括可选参数。为什么在函数定义中formData参数需要在cb参数之前?这可能会起作用,但可能会成为维护的噩梦@AndFisher——如果不不断添加更多可选参数,这就不是维护的噩梦。正如答案所说,正确的方法是切换到选项对象,但OP已经表示不可能,因为此时他们无法更改所有其他呼叫者。因此,考虑到这一限制,没有其他选择。考虑到所提出的约束条件,您知道有其他方法来回答这个问题吗?这将违背文档注释的概念,这可能会使可能继承但不熟悉项目的新开发人员感到困惑,从而导致维护问题。@NithilaShanm