同期コードと非同期コードが混在しています。私はコメントで何が起こっているかを説明しようとするでしょう:
まず、あなたの関数の定義 - あなたが適切
// I've re-spaced the code slightly and removed your comments so mine stand out
function resize(img) {
Jimp.read(img.path).then(function (err, file) {
// this code only executes after the file is done reading, but this
// is an asynchronous action - it doesn't hold up execution
if (err) throw err;
file.resize(200, 200).quality(70).write(newPath);
// .write() is presumably *also* an asynchronous action - if you want
// something to happen only *after* it's been written, it needs to be in
// a callback or promise on the write method
});
// I added this explicitly - after you *start* your Jimp.read, you *immediately*
// return from this function, *before* the read is completed. If you want
// something to happen only *after* your read and write, you either need to
// return the promise so you can act on it, or put the further actions in a callback
return undefined;
}
function rec(imgObjArray) {
if(_.isEmpty(imgObjArray)) return;
// resize() runs and returns *before* the file is read, resized, and written
resize(imgObjArray.pop());
// I don't know what fn() is, it's not defined here - presumably it's not important
fn(imgObjArray);
}
...そして、あなたの手続きの呼び出しを自分の補完を処理せずに、非同期アクションをオフに発射している:
// this fires off and completes immediately, having initiated the asynchronous methods
rec(imgObjArray);
// you call this on the assumption that all of your code above has completed, but since
// it's asynchronous, that's not true, you get here with *none* of your images completed
nsg({
src: [
'out/images/desktop/*.jpg'
],
spritePath: 'out/images/desktop/sprite.jpg',
compositor: 'jimp'
}, function (err) {
console.log('Sprite generated!');
});
あなたは2つのオプションがあります。file.write()
は同期呼び出しで、あなただけの私に約束と行動を返すことができる場合
をT:約束の構文が正しくない場合
function resize(img) {
// by *returning* this call, we're actually returning the promise, we can act on
// in the future
return Jimp.read(img.path).then(function (err, file) {
if (err) throw err;
file.resize(200, 200).quality(70).write(newPath);
});
}
function rec(imgObjArray) {
if(_.isEmpty(imgObjArray)) return;
// the result of resize is now a promise
return resize(imgObjArray.pop()).then(function(err) {;
// again, assuming `fn()` is synchronous...
fn(imgObjArray);
});
}
// now the result of *this* call is a promise, which you can use to control
// the timing of your next call
rec(imgObjArray).then(function(err) {
// now this will only run after all of the previous calls have executed
nsg({
src: [
'out/images/desktop/*.jpg'
],
spritePath: 'out/images/desktop/sprite.jpg',
compositor: 'jimp'
}, function (err) {
console.log('Sprite generated!');
});
});
...謝罪、私は彼らがユビキタスになった積極ので、ノードを使用していません。
サブコールが非同期であっても、同じ方法で約束を使用する方法がありますが、私はそれを準備していません。
そうでない場合、あなたはあなたの関数にコールバックを渡すことができます。
function resize(img, cb) {
// ... you get the idea...
file.resize(200, 300).quality(70).write(newPath, cb);
}
function rec(imgObjArray, cb) {
// ... you get the idea...
resize(imgObjArray.pop(), cb);
}
rec(imgObjArray, function(err, response) {
nsg({
src: [
'out/images/desktop/*.jpg'
],
spritePath: 'out/images/desktop/sprite.jpg',
compositor: 'jimp'
}, function (err) {
console.log('Sprite generated!');
});
});
は、この情報がお役に立てば幸い!
もしあなたが約束を持っていたら、最初のアクションが実行されたときに次のアクションを実行するためにそれを使用する必要があります。コードを修正する方法に関する有用なガイダンスを提供するために、コードを、またはタスクの移行先の少なくとも一部に見ておくと便利です。 – Jason
私もそう思ったので、スプライトシートコードを実行するfn-callを含むjimpキューにthen()関数を作成します。しかし、私は同じ問題を抱えています。 – Zantinger
コードを表示する必要があります。コードに関する質問は、あなたの質問に関連するコードを含まなければなりません。コードを表示すると数分で助けてくれるかもしれません。 – jfriend00