2016-10-23 1 views
1

Ich habe diese multiple Funktion namens checkForURLS, die zwei weitere Funktionen aufruft, die Rückrufe zurückgeben, wie kann ich das Array hinzufügen, sobald beide Rückrufe zurückgegeben haben und dann das Array als Rückruf zurückgeben? Ich arbeite mit reinem JavaScript.Mehrere Callback-Antworten zum Array hinzufügen

function checkForURLs(uniqueURL, customURL, callback) { 
    var errors = []; 

    checkForUniqueURL(uniqueURL, function(UniqueURLCallback) { 
     if (UniqueURLCallback===true) { 
      errors.push("This unique URL is already taken, please try another."); 
     } 
    }); 

    if (customURL.length>0) { 
     checkForCustomURL(customURL, function(customURLCallback) { 
      if (customURLCallback===true) { 
       errors.push("This custom URL is already taken, please try another."); 
      } 
     }); 
    } 

    if (errors.length>0) { 
     return callback(errors); 
    } else { 
     return callback(false); 
    } 
} 
+0

Ihr Code arbeiten sollte. Sie rufen '' 'checkForURLs (urlA, urlB, function (error) {/ * behandeln Ihren Fehler in der Callback-Funktion * /});' ''. Ist das nicht, was du willst? Was willst du? – Dario

+0

Es scheint, leer zurück zu kommen, aber wenn ich einen Callback in einen der inneren Callbacks, um den Rückruf (Fehler) zurückgeben, funktioniert es aber nur für diesen bestimmten Rückruf. Was passiert, ist, dass die if-Anweisung nicht wartet und einfach sofort zurückkehrt. Mit jQuery hätte ich etwas wie 'done' verwendet und wäre dann aber nicht sicher wie man es in JavaScript machen würde. –

+1

klingt wie 'checkForUniqueURL()' tut etwas asynchron und all dies sollte mit Versprechungen getan werden. Zeigen Sie alle relevanten Code – charlietfl

Antwort

1

können Sie verwenden Promise Konstruktor new Promise(function), Promise.all() Aufgabe auszuführen, wenn checkForUniqueURL und checkForCustomURL Rückrufe genannt wurden.

function callback(value) { 
 
    return value 
 
} 
 

 
function checkForUniqueURL(url, callback) { 
 
    return new Promise(function(resolve, reject) { 
 
    setTimeout(function() { 
 
     resolve(callback(true)) 
 
    }, Math.random() * 1500) 
 
    }) 
 
} 
 

 
function checkForCustomURL(url, callback) { 
 
    return new Promise(function(resolve, reject) { 
 
    setTimeout(function() { 
 
     resolve(callback(true)) 
 
    }, Math.random() * 1500) 
 
    }) 
 
} 
 

 
function checkForURLs(uniqueURL, customURL, callback) { 
 
    var errors = []; 
 

 
    return Promise.all([ 
 
    new Promise(function(resolve, reject) { 
 
     checkForUniqueURL(uniqueURL, function(UniqueURLCallback) { 
 
     if (UniqueURLCallback === true) { 
 
      errors.push("This unique URL is already taken, please try another."); 
 
     } 
 
     resolve() 
 
     }) 
 
    }) 
 
    , new Promise(function(resolve, reject) { 
 
     if (customURL.length > 0) { 
 
     checkForCustomURL(customURL, function(customURLCallback) { 
 
      if (customURLCallback === true) { 
 
      errors.push("This custom URL is already taken, please try another."); 
 
      } 
 
      resolve() 
 
     }); 
 
     } 
 
    }) 
 
    ]) 
 
    .then(function() { 
 
    console.log(errors); 
 
    if (errors.length > 0) { 
 
     return Promise.resolve(callback(errors)); 
 
    } else { 
 
     return Promise.reject(callback(new Error("false"))); 
 
    } 
 
    }) 
 
} 
 

 
checkForURLs("abc", "def", callback) 
 
    .then(function(errs) { 
 
    console.log(errs); 
 
    }) 
 
    .catch(function(err) { 
 
    console.log("err:", err.message) 
 
    })

+0

@PaulNess Siehe aktualisierten Beitrag. Anpassung von 'resolve()' nach außerhalb von 'if''. Wenn "errors.length> 0" vorher "false" war, wurde 'reject()' nicht aufgerufen. – guest271314

0

Wenn alle Funktionen, die Sie synchron verwenden sind und ähnlich der folgenden implementiert, arbeitet Sie Code sehr gut:

function checkForURLs(uniqueURL, customURL, callback) { 
 
    var errors = []; 
 

 
    checkForUniqueURL(uniqueURL, function(UniqueURLCallback) { 
 
     if (UniqueURLCallback===true) { 
 
      errors.push("This unique URL is already taken, please try another."); 
 
     } 
 
    }); 
 

 
    if (customURL.length>0) { 
 
     checkForCustomURL(customURL, function(customURLCallback) { 
 
      if (customURLCallback===true) { 
 
       errors.push("This custom URL is already taken, please try another."); 
 
      } 
 
     }); 
 
    } 
 

 
    if (errors.length>0) { 
 
     return callback(errors); 
 
    } else { 
 
     return callback(false); 
 
    } 
 
} 
 

 
// Just test-implement those two functions: 
 
function checkForUniqueURL(url, callback) { callback(true); } 
 
function checkForCustomURL(url, callback) { callback(true); } 
 

 

 
errors = checkForURLs("test", "test2", function(errors) { 
 
    console.log(errors); 
 
    return "I have got some errors!"; 
 
}); 
 

 
console.log(errors);

Wenn in der Tat Ihr Code hat asynchrone Teile, Sie würde mit der return callback() warten müssen, bis diese fertig sind. Vielleicht, indem Sie sie in einen anderen Rückruf einpacken?

0

Dies funktioniert IFF Ihre checkForUniqueURL und checkForCustomURL Funktionen synchron sind. Hier ist ein Beispiel dafür Arbeits mit Synchron Funktionen ...

https://jsfiddle.net/ojh5b1f8/

Aber ich gehe davon aus, da seine nicht funktioniert, dass Ihre Funktionen asynchron sind. Hier ist ein Beispiel dafür nicht mit asynchronen Funktionen arbeiten ...

https://jsfiddle.net/uzjbyrt7/

Es funktioniert nicht, weil die checkForURLs Funktion zurückkehrt, bevor die Rückrufe ausgelöst werden. Die beste Lösung in diesem Fall ist Promises. Sie werden jedoch wahrscheinlich eine Bibliothek verwenden müssen, um Unterstützung zu erhalten, da sie noch nicht in allen Browsern implementiert sind. Ich empfehle bluebird.js. Hier ist ein Beispiel davon mit asynchronen Funktionen und verspricht arbeiten ...

https://jsfiddle.net/ynxcu7t6/

Verwandte Themen