Javascript 如何在将承诺与非承诺调用链接时避免传播

Javascript 如何在将承诺与非承诺调用链接时避免传播,javascript,ecmascript-6,es6-promise,Javascript,Ecmascript 6,Es6 Promise,我希望下面的代码不要调用OK逻辑,也不要拒绝承诺。注意,我混合了承诺和非承诺调用(在从非承诺步骤返回字符串后,仍然设法保持thenable),如果p1解析为非OK值,我只希望承诺保持在pending状态 const p1 = new Promise((resolve, reject) => { resolve("NOT_OK_BUT_NOT_A_CATCH_NEITHER"); }); p1.then(result => { if (result !== "OK")

我希望下面的代码不要调用OK逻辑,也不要拒绝承诺。注意,我混合了承诺和非承诺调用(在从非承诺步骤返回字符串后,仍然设法保持
thenable
),如果
p1
解析为非OK值,我只希望承诺保持在
pending
状态

const p1 = new Promise((resolve, reject) => {
    resolve("NOT_OK_BUT_NOT_A_CATCH_NEITHER");
});

p1.then(result => {
    if (result !== "OK") {
        return "How do I avoid calling OK logic w/out rejecting?";
    }
    else {
        return Promise.resolve("OK");
    }
}).then(result => {
    console.error("OK logic...");
});

您有两个选择:

1) 抛出一个错误:

p1.then(result => {
  if (result =='notOk') {
    throw new Error('not ok');
  } else {
    return 'OK';
  }
})
.then(r => {
  // r will be 'OK'
})
.catch(e => {
  // e will be an error with message 'not ok', if it threw
})
第二个
。然后
将不运行,
.catch
将运行

2) 决定在后一种情况下做什么
。然后有条件地:

p1.then(result => {
  if (result =='notOk') {
    return 'not ok'
  } else {
    return 'OK';
  }
})
.then(r => {
  if (r === 'OK') {
    // do stuff here for condition of OK
  }
})
这是因为第二个
.then
将前一个
返回的任何内容作为参数。then
(但是,如果前一个.then返回了承诺,则第二个.then的参数将是异步解析的任何内容)


注意:如果您
.catch
捕获一个出错的承诺,并返回该承诺,则最终承诺不会有错误,因为
.catch
捕获了它。

找到了一种方法,不确定它有多好,但它是有效的。我们的想法是一直把它作为承诺,而不是在不需要的时候解决

在我的例子中,它为我省去了管理可忽略结果的麻烦,而不必使用
processable
标志等来污染结果

const p1 = new Promise((resolve, reject) => {
    resolve("NOT_OK_BUT_NOT_A_CATCH_NEITHER");
});

p1.then(result => {
    return new Promise((resolve, reject) => {
        if (result === "OK") {
            resolve(result);
        }
        // OR do nothing
        console.error("Just Do nothing");
    });
}).then(result => {
    console.error("OK logic...");
});

最好的方法是不要以这种方式连锁。而是这样做:

const p1 = new Promise((resolve, reject) => {
    resolve("NOT_OK_BUT_NOT_A_CATCH_NEITHER");
});

p1.then(result => {
    if (result !== "OK") {
        return "How do I avoid calling OK logic w/out rejecting?";
    } else {
        return Promise.resolve("OK")
            .then(result => {
                console.error("OK logic...");
            });
    }
})
如果你在写一个线性链,这意味着你在说你想要一步一步的执行,这不是你想要的

或者,如果您的目标平台/构建系统支持它,请将其作为异步函数编写:

(async function() {
    const result = await Promise.resolve "NOT_OK_BUT_NOT_A_CATCH_NEITHER");

    if (result !== "OK") {
        return "How do I avoid calling OK logic w/out rejecting?";
    } else {
        await Promise.resolve("OK");

        console.error("OK logic...");
    }
})();

当你使用承诺时,你要么决心获胜,要么拒绝失败。没有中间立场。双关语意图不解决将使你处于中间立场。不确定它在内存管理等方面有多好-但它确实起到了作用。不要拒绝,因为这不是一个错误,它只是一些不值得处理的东西。额外的然后-可能会工作,但我认为我最好使用显式挂起的承诺。挂起的承诺是一个(非常小的)内存泄漏。您可以选择将结果作为打包对象返回,
if(isOK(result)){resolve({result:result,status:'OK'})}
,然后在下一个
中检查状态,如果它不是“OK”,就立即返回null或其他什么,但是我必须找到一种方法来防止它泄漏到下一个“then”等等,我宁愿早点切断它。哦,我明白了。我不知道它是否被链接。该函数是链接的一部分-从中返回会导致原始问题。